0

I had been trying to read input from a file, but it seems that something doesn't work correctly...Instead of reading the word "Words" that exists in the text,the printf is always showing 2 additional random characters not included in the file...

The function is:

void search(struct word *w,FILE *f){

    char *c;
    char c2;
    int i,j,k,l;
    c=(char*)malloc(120*sizeof(char));                     

    i=1;             
    while(f!=NULL) { 
        c2=fgetc(f);

        while(c2!=EOF) {
           while(c2!='\n') {  
              k=0;
              while(c2!=' ') {
                  *(c+k)=c2;
                  k=k+1;
                  c2=getc(f);
              }
              if(w->name==c) 
                  insert(i,j+1,name,&w);
              }

              memset(c, 0, sizeof(c));
              j=j+k+1;
          }
          i=i+1;
       }
    }
}

the main function is

int main()
{
    struct word *s;
    s=(struct word*)malloc(sizeof(struct word));
    s->name=(char*)malloc(20*sizeof(char));
    s->result=NULL;
    scanf("%s",s->name);
    search(s);
    printres(s);
    system("pause");
    exit(0);
}

and the structs are

struct position
{
    char *filename;
    int line;
    int place;
    struct position *next;
};
struct word
{
    char *name;
    struct word *right;
    struct word *left;
    struct position *result;
};

Why do these additional 2 characters appear? What should I do?

user3697730
  • 251
  • 1
  • 3
  • 13
  • 1
    You forgot to call `fflush`. And you should compile with all warnings & debug info (e.g., if using [GCC](http://gcc.gnu.org/), with `gcc -Wall -g`) and **use the debugger**. BTW, your question is probably operating system specific (perhaps related to end of file markers). And your code is awfully indented. Please edit your question to improve the indentation & formatting. – Basile Starynkevitch Jul 13 '14 at 16:12
  • Can you explain better what are you trying to read from the file? What's the file's structure? – Alessandro Suglia Jul 13 '14 at 16:29
  • Please sort out the indentation – Ed Heal Jul 13 '14 at 16:30
  • The file is: Words are flowing out like endless rain into a paper cup They slither wildly as they slip away across the universe Pools of sorrow, waves of joy are drifting through my open mind Possessing and caressing me I am supposed to search for a specific word in that file...That specific word is called w->name...In case I find it,I must do something else that works... – user3697730 Jul 13 '14 at 16:34
  • As I am a beginer at programming,allow me to ask...What does identation mean? – user3697730 Jul 13 '14 at 16:35
  • @user3697730 open file in emacs press `CTRL-x h` now press `TAB` now code looks much nicer! That's indentation! :p – Nullpointer Jul 13 '14 at 16:44
  • "Indentation" is how you format your code with spaces and tabs, and where you set the braces. You really want to have a consistent indentation to make your code more readable. See also ["Indent style" on Wikipedia](http://en.wikipedia.org/wiki/Indent_style) on some examples. Note that there is no "correct" way to indent your code, it's a matter of taste (and the source of everlasting Holy Wars in programming). – DarkDust Jul 13 '14 at 18:13

3 Answers3

1

at first glance, this seems wrong to me

memset(c, 0, sizeof(c));

mainly because c it's a char*, then sizeof(c) will depend of compilation details... And this test is wrong also:

if(w->name=c)  

you probably want

if(strcmp(w->name,c) == 0)

after terminating the buffer by '\0'.

Also, you should check to not overflow your buffer, otherwise results will be unpredictable.

CapelliC
  • 59,646
  • 5
  • 47
  • 90
  • Actually,I have almost made it...There is still one problem though...The function does not stop! My new code is: – user3697730 Jul 13 '14 at 17:15
  • @user3697730 you edit the question. (without replacing the previous code) and then add the new code You specify that you have changed the code. – BLUEPIXY Jul 13 '14 at 22:48
1

Indentation means you're not arranging your code in a properly readable manner.

I assume you're trying to store words line by line and word by word from a text file. But I'm unable to make out what your insert() function does. Besides, this code has a lot of faults.

I'll list them out first, and then you can state what you're exactly doing in this.

  1. in main(): search(s)->file pointer parameter missing.

    The prototype is : void search(struct word *w,FILE *f).

    You have to do the following:

    • first open the file by using fopen() function.
    • use the pointer obtained from step i. and insert it as a parameter in your search() function.

    This is just the solution I'm giving, you lack knowledge in this. You'll have to read a lot more on using files in c.

  2. statement if(w->name=c):

    • It's "==" and not "=". Here you only assigned w->name as c.
    • You were trying to compare pointers and not the characters in them! Comparing pointers will be no use. You allocated different memory for both, how can the addresses be same? Read more on comparing strings in c.
    • Before comparing, you have to terminate a string with '\0'(null character). This often leads to unwanted characters being printed otherwise.

There'll be a lot of resources online which will have the exact answer to what you want to do. You can use a Google search. I can only point out so many faults, since your entire code has faults here and there. Learn more I'd say.

Community
  • 1
  • 1
mb1994
  • 241
  • 3
  • 13
1

I haven't studied the logic of your code, so I'm just going to point out some of the problems:

c=(char*)malloc(120*sizeof(char));                     

The cast here is mostly useless. It can be used to warn you when you try to allocate data of the wrong type, but many people recommend the following way to allocate memory:

c = malloc (120 * sizeof *c);

This automatically allocates 120 items of the right size, regardless of the actual type of c. You should also check the return value of malloc(). Allocations can fail.

char c2;
c2=fgetc(f);

while(c2!=EOF) {

The fgetc() function returns a signed int representing a character in the range of an unsigned char, or EOF which is a negative value.

Plain char is either compatible with signed char or unsigned char. If it is unsigned, then it can never store the value of EOF, so the comparison c2 != EOF will always be false. If it is signed, then it can (typically, not necessarily) store EOF, but it will have the same value as an actual character.

You should store the return value of fgetc() in an int variable, compare it to EOF, and then convert it to char.

if(w->name==c) 

Is this meant to be a string comparison? It doesn't work that way in C. You're only comparing pointers. To compare the actual strings, you'd have to call strcmp() or similar.

insert(i,j+1,name,&w);

(Undefined function)

memset(c, 0, sizeof(c));

I assume that you're trying to set the entire buffer to 0, but the size is wrong. This zeroes sizeof (char *) bytes, not the 120 bytes you allocated.

s=(struct word*)malloc(sizeof(struct word));
s->name=(char*)malloc(20*sizeof(char));

Pointless casts an no check for allocation failure. This should be (in my opinion):

s = malloc (sizeof *s);
if (s) {
  s->name = malloc (20 * sizeof *s->name);
}
if (s && s->name) {
  /* Go to work */
} else {
  /* Allocation failure */
}

/* All done. Free memory. */
if (s) {
  free (s->name);
}
free (s);

Because free(0) is a no-op, this cleanup works with all of the branches above.

search(s);

The search() function wants a second argument (FILE *).

printres(s);

(Undefined function)

Nisse Engström
  • 4,738
  • 23
  • 27
  • 42