mayar.m
mayar.m

Reputation: 1

Scanning from a file in C

I am trying to scan a string from a file using the code below. But my program prints weird characters. Any ideas how to stop this and how to keep spaces between words when printing the string?

here are the contents of the file (test.txt)  (test.txt)

Here is the output of my program:

output

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct
{
   char word[80];
   int length;
   int freq;
} sent;

int main()
{
   sent a[50];
   int v,status;
   int i=0,cnt=0;
   char*y;

   FILE*p;
   p=fopen("C:\\Users\\User\\Desktop\\test.txt","r");
   status=fscanf(p,"%s",a[i].word);
   while(status !=EOF){
      i++;
      status=fscanf(p,"%s",a[i].word);
   }
   for(i=0;i<50;i++)
   {
      char *y=strtok(a[i].word,"!@#$%&*?.");

      while(y!=NULL)
      {
         printf("%s",y);
         y=strtok(NULL,"!@#$%&*?.");

      }
   }
}

Upvotes: 0

Views: 112

Answers (2)

Soren
Soren

Reputation: 14688

As people have commented, you are likely not having 50 words in the file you read, but your loop tries to loop over 50 anyway...., so this line

for(i=0;i<50;i++)

should be modified to

int w;
for(w=0;w<i;w++)

and you should replace the use of i with w inside the loop (or maybe you intended to use the variable cnt inside the while loop, since that is currently unused in your code).

And you need protection for buffer overruns that would happen if your file would have more than 50 words etc, but that is beyond the scope of this answer.

Update to answer your comment:

To have space between the words, you simply just add them to the output, like

printf("%s ",y);

Your scanf will however terminate the string scan at any space, so space (hex 20), newline (\n), tab (\t) or return (\r) will all be terminating characters for your strings -- If you want to preserve and output the same, you simply just scan for those as well, like

  char theString[50];
  char theSpace;
  int matched = scanf("%s%c",theString, theSpace);

and if matched == 2 then you have scanned both a string and the space that terminated the scan, and you can print it like

  printf("%s%c",theModifiedString,theSpace);

Upvotes: 2

Niklas Rosencrantz
Niklas Rosencrantz

Reputation: 26647

It's just string manipulation. I debugged and modified your program a little so that there is text output instead of junk. You might need to modify it some more, but it does print the contents of the file now. The reason you got junk character is that the loop doesn't know when to stop when the string is not terminated, so you get memory contents from something else. The recommended way is fgets to read a file and whitespace is preserved.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    char *word;
    int length;
    int freq;
} sent;

int words(const char *sentence) {
    int count, i, len;
    char lastC;
    len = strlen(sentence);
    if (len > 0) {
        lastC = sentence[0];
    }
    for (i = 0; i <= len; i++) {
        if (sentence[i] == ' ' && lastC != ' ') {
            count++;
        }
        lastC = sentence[i];
    }
    if (count > 0 && sentence[i] != ' ') {
        count++;
    }
    return count;
}

int main() {
    sent a[50];
    int v, status;
    int i = 0, cnt = 0;
    FILE *p;
    p = fopen("data.txt", "r");
    char buf[100], title[100];
    fgets(buf, sizeof buf, p);
    int j = words(buf);
    char *yy;
    yy = strtok(buf, "!@#$&*?%.");

    while (yy != NULL) {
        a[i].word = yy;
        yy = strtok(NULL, "!@#$&*?%.");
        i++;
    }

    for (int k = 0; k<i; k++) {
        printf("%s", a[k].word);
    }
}

The program tokenizes the buffer and keeps the whitespace. I changed the way you read the file to fgets.

data.txt

On a scale from one to ten what$ is your favorite color of the alphabet

output

On a scale from one to ten what is your favorite color of the alphabet

Upvotes: 0

Related Questions