Page 1 of 2

The C pro

Posted: Sat Oct 02, 2004 11:48 am
by rich_m
its just that i have a problem with this pro: This program is used 2 insert a string into an existing string. for eg. here's a sample output:

Code: Select all

Enter the text:Hello how r u?
Enter new word to add: fat
Enter position of insertion:10
Hello how fat r u?
problem is i'm unable 2 get this output excactly
here's my program

Code: Select all

#include<stdio.h>
#include<conio.h>
void main()
{
 int i,j,k,l,a,x,z,p;
 char text[100],ntext[100],atext[100],rtext[100];
 clrscr();
for(i=0;i<=100;i++); //clearing up arrays
 {
   text[100]='\0';
  ntext[100]='\0';
  atext[100]='\0';
  rtext[100]='\0';
 }
 printf("\Enter the text:");//getting the main sentence
 for(i=0;((text[i]=getchar())!='\n');i++);
 z=i;
  printf("Enter the new word to add:");//getting word 4 insertion
  for(j=0;((ntext[j]=getchar())!='\n');j++);
  x=i+j+1;
   printf("Enter position of insertion:");//get location
   scanf("%d",&a);
    /* PROCESSING*/
   p=a-1;
for(l=0;l<=p;l++) //sending the part before 'a' into another array
 atext[l]=text[l];
for(i=0;i<=j;i++,l++)//adding insertion word
 atext[l-1]=ntext[i];
i=a-1;
for(k=0;k<=z-p;k++,i++)//storing the part after 'a'
 rtext[k]=text[i];
for(i=0;i<=z;i++,l++)//adding the left over
 atext[l-1]=rtext[i];
for(i=0;i<=x;i++)//printing the new array
 printf("%c",atext[i]);
getch();//used 4 execution convienence
}
why does the second half come on a separate line.

Re:The C pro

Posted: Sat Oct 02, 2004 1:36 pm
by mystran
I hate to give this kind of critic, but (1) could you please write "to" instead of "2" and similar so it would be easier to read your text, and (2) more importantly, it will help yourself, and it will help us, if you try to intend your code properly.

Thanks to your code's "nice" formatting I am unable to decipher what it tries to do but the general solution is here:

Read the text, the new word, and the position of insertion, for example with scanf.

Then use strlen to get the lengths of the two strings.

Then allocate a buffer with the sum of the two lengths, plus the terminating null character. Then copy enough characters to this new buffers from the first buffer to get to the insertion position, then copy the new word where you got, and then copy rest of the original string.

Since you are adding a word, you might want to also add one space before or after the new word, but that might not make sense if you ask for insertion position in characters. Instead, you can ask for insertion position in words, and copy the first string counting spaces, until you have enough words.

Now, you should need at most three loops to do this.

If you want more specific help, you might want to tell use what exactly you WANT from the program, and what exactly it DOES (plus format your code in a more readable form).

Re:The C pro

Posted: Sat Oct 02, 2004 3:18 pm
by rich_m
your right mystran its nearly unreadable (my mistake)
btw i've tried to make it more readable, the program seems to work now. i've attached an exe file for u to check.
Instead, you can ask for insertion position in words, and copy the first string counting spaces, until you have enough words
i don't understand what u mean by those lines,the rest of ur post helped me organize my program.
(i'm a beginner in programming)

Code: Select all

#include<stdio.h>
#include<conio.h>
void main()
{
 int i,j,in,a,x,y,z,l,nt;
 char orginaltext[100],inserttext[100],newtext[100];
 clrscr();
???       /*CLEARING ARRAYS*/
for(i=0;i<=100;i++);
 {
  orginaltext[100]='\0';
   inserttext[100]='\0';
      newtext[100]='\0';
 }
???       /*GETS ORGINAL_TEXT*/
 printf("\Enter the text:");
 for(i=0;((orginaltext[i]=getchar())!='\n');i++);
???       /*TEXT TO INSERT*/
 printf("Enter the new word to add:");
 for(j=0;((inserttext[j]=getchar())!='\n');j++);
 a=i+j;
???       /*GETS POSITION*/
   printf("Enter position of insertion:");
   scanf("%d",&in);
???       /* PROCESSING*/
???       /*COPY FIRST PART*/
 for(x=0;x<=in-1;x++)
  newtext[x]=orginaltext[x];
???       /*INSERT WORD*/
 l=x+1;
 for(y=l,x=0;y<=l+j-1;y++,x++)
  newtext[y]=inserttext[x];
???       /*PASTE THE LEFTOVERS*/
 l=y+1;
 for(z=l,x=in;z<=l+(i-in);z++,x++)
  newtext[z]=orginaltext[x];
???       /*PRINT NEW ARRAY (character by charcter*/
       for(nt=0;nt<=a+2;nt++)
  printf("%c",newtext[nt]);
getch();
}

Re:The C pro

Posted: Sun Oct 03, 2004 2:12 am
by Schol-R-LEA
OK, let's start with the indentation (I'll use Allman style, as that's what I'm used to; for other alternatives, see the Jargon File entry on indent style):

Code: Select all

#include<stdio.h>
#include<conio.h>

void main()
{
    int i,j,in,a,x,y,z,l,nt;
    char orginaltext[100], inserttext[100], newtext[100];
    
    clrscr();
     
    /*CLEARING ARRAYS*/
    for(i=0;i<=100;i++);
    {
        orginaltext[100]='\0';
        inserttext[100]='\0';
        newtext[100]='\0';
    }

    /*GETS ORGINAL_TEXT*/
    printf("\Enter the text:");
    for(i=0;((orginaltext[i]=getchar())!='\n');i++);
    
    /*TEXT TO INSERT*/
    printf("Enter the new word to add:");
    for(j=0;((inserttext[j]=getchar())!='\n');j++);
    
    a=i+j;

    /*GETS POSITION*/
    printf("Enter position of insertion:");
    scanf("%d",&in);

    /* PROCESSING*/
    /*COPY FIRST PART*/
    for(x=0;x<=in-1;x++)
        newtext[x]=orginaltext[x];

    /*INSERT WORD*/
    l=x+1;
    for(y=l,x=0;y<=l+j-1;y++,x++)
        newtext[y]=inserttext[x];
        
    /*PASTE THE LEFTOVERS*/
    l=y+1;
    for(z=l,x=in;z<=l+(i-in);z++,x++)
        newtext[z]=orginaltext[x];

    /*PRINT NEW ARRAY (character by charcter*/
    for(nt=0;nt<=a+2;nt++)
        printf("%c",newtext[nt]);
        
    getch();
}
At least, I'm assuming that that is the desired indentation; the one-liner for() loops, while perfectly legal code, are a real pain to read as they tend to look like a mistake even with meticulous indentation, so I may be wrong somewhere. I'll critique the code itself in the next posting, to avoid the post size limitation.

Re:The C pro

Posted: Sun Oct 03, 2004 2:12 am
by Schol-R-LEA
Ah, where to begin? Well, how about the fact that [tt]main()[/tt] has to be an [tt]int[/tt] - it may seem odd, but in fact the return value of a program often is quite important for indicating error conditions to the system, or to a calling shell script. It's a common error, so no big deal.

The next problem is in the loop you use to clear the arrays. Setting aside there is a better way to do this - [tt]memset()[/tt], which I assume your prof hasn't covered yet - you have a serious problem with the array subscripting.

Code: Select all

    for(i=0;i<=100;i++);
    {
        orginaltext[100]='\0'; 
                    ^^^
        inserttext[100]='\0';
                    ^^^              
        newtext[100]='\0';
                 ^^^    
    }
Each of these needs to be 'i'; as it is, you are clearing the 100th item one hundred times.

Wait, did I say 100th item? I'm sorry, that's wrong - C arrays begin at subscript zero, so the item at subscript 100 is the 101st item, which is off the end of the array entirely. At best, you're clearing a memory location not in your array; at worst, you're overwriting some other variable, making for a very nasty and hard to track bug. Again, this kind of off-by-one error is a common novice mistake, and even experienced coders sometimes make it when they aren't paying attention. Change [tt]i<=100[/tt] to [tt]100 > i[/tt] and you're in business. Oh, the reversed order? That's a trick a lot of experienced C coders use; that way, if you type [tt]=[/tt] instead of [tt]==[/tt], [tt]!=[/tt], [tt]>=[/tt] or [tt]<=[/tt], you get a compiler error instead of silently reassigning a variable you meant to test.

Re:The C pro

Posted: Sun Oct 03, 2004 3:57 am
by Schol-R-LEA
I think I may well cry. I just spent over an hour writing a long advice post, with all kinds of annotations; and in a moment of carelessness, I saved over it with an early version that only covered a small part of it. ARRGH!

Re:The C pro

Posted: Sun Oct 03, 2004 4:11 am
by Schol-R-LEA
To try and recreate at least part of what I said:

Except for trivial things, such as loop indices whose values aren't used otherwise, you should always use variable names that are as descriptive as possible. Using the lowercase letter 'l' as a variabhle name is especially unwise, as it is too easily mistaken for the numeral '1'.

Similarly, I would strongly recommend using named constants instead of magic numbers. For example, you can [tt]#define[/tt] the size of the buffers rather than inserting a 100 in every array declaration, as well as the limit on the for loops. That way, if you have to change it, you only need to change one line rather than several.

If your professor has explained about writing separate functions, then I would advise writing a function for each of the sections which you marked off with a comment, and save the comments for explaining the code itself. for example, you could write a function to clear the buffers:

Code: Select all

char* clear_buffer(char buf[], int size)
{
    int i;

    for (i = 0; size > i; i++)
        buf[i] = '\00';

    return buf;
}
You might also consider using the standard string functions, if the project permits you to; note that the fixed-limit versions (e.g., strncpy()) are preferably to the unlimited-extent equivalents (e.g., strcpy()).

Re:The C pro

Posted: Sun Oct 03, 2004 11:13 am
by rich_m
thanks all this is new, but it sure lit an interest in my program, as to how each part of my program makes difference , next time i'll be a lot carful, btw do u have any suggestions for tutorials etc for new programmers :)

Re:The C pro

Posted: Sun Oct 03, 2004 4:39 pm
by Schol-R-LEA
Regarding suggestions, I would point you in the direction of the Novice Programmer Advice thread; if you haven't read it yet, I strongly recommend you do.

Similarly, you should read the essay "How to Ask Questions the Smart Way" by Eric S. Raymond, to help polish your posting style. I know it may seem harsh, but really does pay to post carefully and thoughtfully. You might want to read some of Raymond's other advice essays and FAQs, and (just in case you didn't get the hint earlier) peruse through the Jargon File as well, if only to get a good handle on the mindset. However, I would recommend taking anything ESR says with a grain of salt, especially when he's bashing M$, as his ego tends to pontificate blindly when he isn't watching. ::)

I'd further recommend honing your search-fu, as very often the answers to a question can be found with a judicious use of Google and other search engines. If you use a browser with a built-in search tool, such as Firefox or Opera, you might want to have a number of technically-oriented search engines in your search list to help you quickly refine difficult searches by using the appropriately specialized search.

Try reading as much code as you can get your hands on. Not all of it will be easy to read - there's a tremendous amount fo garbage code around - but it should help familiarize you with the idioms used by C programmers.

After you have C down solidly, I'd recommend learning at least one other language (if you haven't already). The better you understand programming in general, the better you'll be as a programmer in all languages. <ego>You can start with my Scheme overview, which is short and (I hope) easy to understand.</ego> If you do read it, let me know what you think; I can always use some feedback on how ro improve it.

For books, you'll want to get a copy of The C Programming Language by Kernighan and Ritchie, which is the definitive text on C. I'd also recommend the latest version of C Primer Plus. If you are considering learning C++ later, you might want to get a copy of Thinking in C++, vol. I, and watching the "Thinking in C" video on the CD-ROM that comes with it.

For tutorials, you might try a few of the following (not reviewed, I can't comment on their quality):

http://www.lysator.liu.se/c/bwk-tutor.html - an online tutorial written by Brian Kernighan himself! WIIGI!

http://www.freshsources.com/thinkc.html
http://www.physics.drexel.edu/courses/C ... orial.html
http://www.cs.cf.ac.uk/Dave/C/CE.html
http://www.cprogramming.com/
http://cplus.about.com/library/blctut.htm
http://www.strath.ac.uk/IT/Docs/Ccourse/

And, of course, feel free to ask for help whenever you need it.

Re:The C pro

Posted: Sun Oct 03, 2004 5:59 pm
by mystran
Didn't ESR support personal nuclear weapons too?
Or was that someone else?

Re:The C pro

Posted: Mon Oct 04, 2004 10:04 am
by zloba

Code: Select all

for(i=0;i<=100;i++); // i=101;
    {
        orginaltext[100]='\0';
                    ^^^
        inserttext[100]='\0';
                    ^^^             
        newtext[100]='\0';
                ^^^   
    }
Each of these needs to be 'i'; as it is, you are clearing the 100th item one hundred times.
better yet, that does NOTHING 100 times, effectively i=101; the slow and painful way (mind the semicolon), and then clears 101th item once..
not that it makes a difference in the end result ;)

Re:The C pro

Posted: Mon Oct 04, 2004 2:26 pm
by Schol-R-LEA
I know; see the paragraph following that one in my original post:
Wait, did I say 100th item? I'm sorry, that's wrong - C arrays begin at subscript zero, so the item at subscript 100 is the 101st item, which is off the end of the array entirely. At best, you're clearing a memory location not in your array; at worst, you're overwriting some other variable, making for a very nasty and hard to track bug. Again, this kind of off-by-one error is a common novice mistake, and even experienced coders sometimes make it when they aren't paying attention. Change i<=100 to 100 > i and you're in business. Oh, the reversed order? That's a trick a lot of experienced C coders use; that way, if you type = instead of ==, !=, >= or <=, you get a compiler error instead of silently reassigning a variable you meant to test.
;)

Re:The C pro

Posted: Mon Oct 04, 2004 2:30 pm
by Schol-R-LEA
mystran wrote: Didn't ESR support personal nuclear weapons too?
Or was that someone else?
I'm not sure, but for the life of me, he might have said that. Probably as a joke, but you never know...

Re:The C pro

Posted: Mon Oct 04, 2004 2:39 pm
by mystran
I would like to mention one more issue: one should Know, that allocating buffers from stack like this will directly result in a known exploitation technique known as "buffer overflow". Not that allocating from heap really helps. If somebody feeds your program more than 100 bytes of stuff, they will be able to install arbitary code in the process.

What does help though, is check for the maximum length. Scanf can do this, simply replace "%s" with "%99s". 99 is the number of characters that fits into your buffer, which is one less than the length of the buffer because the final NUL character also needs one byte (and is not included in the count that scanf takes).

It probably won't matter in an exercise like this, but it's definitely better to pick a good habbit than a bad one, especially when the fix is this simple.

Re:The C pro

Posted: Sat Oct 23, 2004 1:12 pm
by rich_m
since the text that the program gets as input is not known, it is not possible to allocate memory dynamically..(am I right).

when i initialize char a[20] is 20bytes or 21 bytes allocated.
btw i've attached the file, i'd like to know if by any possible input the program crashed.