0

I am learning file handling in C. I wrote code to replace a line in a file with a string input by the user. The replacing progress itself works great, but somehow the first line is always empty and I am able to understand what goes wrong.

Additionally I have some additional questions about file handling itself and about tracking down the mistakes in my code. I understand by now that I should have used perror() and errno. This will be the next thing I will read on.

  • Why shouldn't I use "w+" establishing the file stream? (A user on here told me to better not use it, unfortunately I couldn't get an explanation)
  • I tried to use gdb to find the mistake, but when I display my fileStored array I get only numbers, since its obviously an int array, how could I improve the displaying of the variable
  • What would be a good approach in gdb to track the mistake down I made in the code?

The code:

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

#define MAXLENGTH 100

int main(int argc, char *argv[]){

    FILE *fileRead;
    char fileName[MAXLENGTH],newLine[MAXLENGTH];
    int fileStored[MAXLENGTH][MAXLENGTH];
    short lineNumber, lines = 0;
    int readChar;

    printf("Input the filename to be opened:");
    int i = 0;
    while((fileName[i] = getchar()) != '\n' && fileName[i] != EOF && i < MAXLENGTH){
        i++;
    }
    fileName[i] = '\0';

    if((fileRead = fopen(fileName, "r")) == NULL){
        printf("Error: File not found!\n");
        return EXIT_FAILURE;
    }
    i = 0;
    while((readChar = fgetc(fileRead)) != EOF){
        if(readChar == '\n'){
            fileStored[lines][i] = readChar;
            i = 0;
            lines++;
        }
        fileStored[lines][i] = readChar;
        i++;
    }

    fclose(fileRead);
    fileRead = fopen(fileName, "w");

    printf("Input the content of the new line:");

    i = 0;
    while((newLine[i] = getchar()) != '\n' && newLine[i] != EOF && i < MAXLENGTH){
        i++;
    }
    newLine[i] = '\0';

    printf("There are %d lines.\nInput the line number you want to replace:",lines);
    scanf("%d",&lineNumber);

    if((lineNumber > lines) || (lineNumber <=0)){
        printf("Error: Line does not exist!");
        return EXIT_FAILURE;
    }

    int j = 0;

    for(i = 0; i < lines; i++){
        if(i == lineNumber-1){
            fprintf(fileRead,"\n%s",newLine);
            continue;
        }
        do{
            fputc(fileStored[i][j],fileRead);
            j++;
        }while(fileStored[i][j] != '\n');
        j = 0;
    }       

    fclose(fileRead);

    return EXIT_SUCCESS;
}
mrflash818
  • 930
  • 13
  • 24
  • 1) `while((fileName[i] = getchar()) != '\n' && fileName[i] != EOF && i < MAXLENGTH){ i++; }` --> `while((readChar = getchar()) != '\n' && readChar != EOF && i < MAXLENGTH-1){ fileName[i++] = readChar; }` – BLUEPIXY Mar 26 '17 at 10:33
  • 2) `fprintf(fileRead,"\n%s",newLine);` --> `fprintf(fileRead, "%s\n", newLine);` – BLUEPIXY Mar 26 '17 at 10:44
  • 3) `int fileStored[MAXLENGTH][MAXLENGTH];` --> `char fileStored[MAXLENGTH][MAXLENGTH];` – BLUEPIXY Mar 26 '17 at 10:46
  • 4) `do{ fputc(fileStored[i][j],fileRead); j++; }while(fileStored[i][j] != '\n');` --> `fputs(fileStored[i], fileRead);` – BLUEPIXY Mar 26 '17 at 10:49
  • 5) `while((readChar = fgetc(fileRead)) != EOF){ if(readChar == '\n'){ fileStored[lines][i] = readChar; i = 0; lines++; } fileStored[lines][i] = readChar; i++; }` --> `while((readChar = fgetc(fileRead)) != EOF){ fileStored[lines][i++] = readChar; if(readChar == '\n'){ fileStored[lines++][i] = 0; i = 0; } }`. Use `fgets` instead of. – BLUEPIXY Mar 26 '17 at 10:55
  • Thanks for the comments, but I need some more explanation to your code. I think it should stay `int fileStored` since fgetc should return an int and i am passing the value to it from readChar. I also don't like putting `i++` into brackets, since it is not a clear way to represent the code. In general the code works neatly except the first line missing, what I don't understand yet. –  Mar 26 '17 at 11:07
  • 3) It does not have to be `int`. – BLUEPIXY Mar 26 '17 at 11:11
  • 2
    1) `fileName[i] != EOF` You should not compare equal `char` type with EOF. – BLUEPIXY Mar 26 '17 at 11:14
  • 1
    2) `"\n%s"` : It is probably a mistake to output a newline before the contents. It should be line-by-line processing. – BLUEPIXY Mar 26 '17 at 11:15
  • 4) Because it is incrementing after outputting the character, the comparison of the termination condition is incorrect. – BLUEPIXY Mar 26 '17 at 11:18
  • 5) Paul Ogilvie already pointed out. It is not correct for reasons similar to (4). Also There is no restriction on the reading line size. It is better to use `fgets`. – BLUEPIXY Mar 26 '17 at 11:21
  • 1
    [getchar(), fgetc() et al always return `int`](http://stackoverflow.com/questions/35356322/difference-between-int-and-char-in-getchar-fgetc-and-putchar-fputc). `EOF` is an `int` value, not `char`. You're correct that `fgetc` returns an int, yet half of your code is storing the value into `char`s and only then comparing against `EOF`. – Antti Haapala -- Слава Україні Mar 26 '17 at 11:26
  • 1
    5-1) Also, it is better to use fgets for cases where there is no newline in the last line. – BLUEPIXY Mar 26 '17 at 11:30
  • Likely duplicate of [How to replace the text into a particular location of a file by passing the argument via command line argument](https://stackoverflow.com/questions/51317431/how-to-replace-the-text-into-a-particular-location-of-a-file-by-passing-the-argu/51319999#51319999) – David C. Rankin Aug 24 '18 at 03:58

0 Answers0