0

I'm new to C programming so if anything looks super wrong I'm sorry!

I need to make my array ( str[512] ) to be exactly 512 characters long after taking input from a text file with an unknown number of characters. After the text file input, there is supposed to be just lowercase 'x' until the 512 characters limit is reached. so if the text file is 'abcdf', my array needs to be 'abcdfxxxxxxxxxxxxxxxxxx(...)xxxxxxx' until there are 512 characters. When I run the program, it's a mess. First part of the code reads the text file, makes all the upper case letters lowercase, skips non alphabet characters and assigns the characters to the array. The second snippet is the problematic one that causes a messy output.

FILE * fp;


char str[512];

int c, i = 0;

fp = fopen("k1.txt", "r");
i = 0;

while(!feof(fp)){
    c = fgetc(fp);
    if (c == '\n') continue;
    c = tolower(c);
    if (c < 97 || c > 122) continue;
    str[i] = c;
    i++;

for(i = 0; i < 512;  ) {
    if (str[i] == '\0') str[i] = 'x';
    i++;    }
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • 1
    @Bananatoid, What text or who suggested using `feof(fp)`? – chux - Reinstate Monica Jun 20 '22 at 20:11
  • In your last section of code (the for loop), why are you resetting the value of `i`? Can you not start from the value at the end of the `while` loop, and then just set all `chars` remaining in the array to `x` (keeping in mind the NUL termination)? – FCo Jun 20 '22 at 20:16
  • `if (str[i] == '\0')` that is not going to work because you never actually fill in `str` with such NUL characters that you are checking for. Instead, `i` is already at the end of the data that was read from file (after you fix the `feof` problem so you should start the `for` loop from that index and not 0. – kaylum Jun 20 '22 at 20:16
  • One easy way would be to first `memset(str, 'x', sizeof str);` and then to pass it as the buffer to fread at most the maximum size into like so: `size_t len = fread(str, 1, sizeof str, stdin);`. Now `len` is the number of bytes actually read, or `0` if the read failed or is short and you then check why. But be careful with the name `str`, because if it's not NUL-terminated it's not a string. – Cheatah Jun 20 '22 at 20:18
  • 3
    no one has linked it yet, see [Why is `while( !feof(file) )` always wrong?](https://stackoverflow.com/questions/5431941/why-is-while-feoffile-always-wrong) – yano Jun 20 '22 at 20:26
  • @chux-ReinstateMonica, I got it from this video https://www.youtube.com/watch?v=8nIilb2kiSU&list=PL6gx4Cwl9DGAKIXv8Yr6nhGJ9Vlcjyymq&index=51 – Bananatoid Jun 20 '22 at 20:31
  • Your problem description doesn't say that normal characters need to be converted to lower case. Also it doesn't say to filter out non-alphabetic characters. So I'm not sure why you implemented it as such. – Cheatah Jun 20 '22 at 20:39
  • @Cheatah, It is a part of what I need to do, the code doing that worked without any problems though so I did not mention that. I just explained what the code snippet does and posted it in case it was the problem after all. – Bananatoid Jun 20 '22 at 20:47
  • @Bananatoid. Thank-you. [It](https://www.youtube.com/watch?v=8nIilb2kiSU&list=PL6gx4Cwl9DGAKIXv8Yr6nhGJ9Vlcjyymq&index=51) is not a good training video. – chux - Reinstate Monica Jun 20 '22 at 20:53

2 Answers2

1

The condition of the while loop is incorrect

while(!feof(fp)){

At least you need to check that i is less than 512

Also this for loop

for(i = 0; i < 512;  ) {
    if (str[i] == '\0') str[i] = 'x';
    i++;    }

does not make a sense because the array after the preceding while loop will not contain the zero character '\0'.

You should write something like the following

int c;
size_t i = 0;
 
while (  i < 512 && ( c = fgetc( fp ) ) != EOF )
{
    if ( isalpha( c ) )
    {
        str[i++] = tolower( c );
    }
}

while ( i < 512 ) str[i++] = 'x';
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

After the text file input, there is supposed to be just lowercase 'x' until the 512 characters limit is reached.

Read the block of up to 512 characters in 1 step.

#define N 512
char str[N];
size_t count = fread(str, 1, N, fp);

// Now copy in the x's
memset(str + count, N - count, 'x');

If you want to print the array, use a precision as str[] is not a string.

printf("<%.*s>\n", N, str);
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256