1

I'm new to programming in c and I've come across a problem with my file system. The aim of this program is for a user to enter a message and that message gets stored in a text file. After the users message gets stored in a text file, they have the choice to 'read' a messaged their loved one has sent to them.

char SingleLine[150];
FILE * filePointer;
FILE * fpointer;
char mess[10];
char reply[100];

case 4:
    printf("enter a message: ");
    fscanf(stdin, "%s", mess);
    filePointer = fopen("gift.txt", "w");
    fprintf(filePointer, "%s \n", mess);
    printf("you said %s \n", mess);
    printf("they wrote something back?, would you like to read it?  yes or no? \n ");
    scanf("%s", &reply);    
    if ((toupper(reply[0]) == 'Y') && (toupper(reply[1]) == 'E') && (toupper(reply[2]) == 'S'))
    {
        printf("you said %s is that true???", &reply);
        printf("ok loading...\n");
        fpointer = fopen("luvtracey.txt", "r");
        while (!feof(fpointer))
            fgets(SingleLine, 150, fpointer);
            puts(SingleLine);
    }
    else if ((toupper(reply[0]) == 'N') && (toupper(reply[1]) == 'O'))
    {
        printf("wow ignorant \n");
    }
    else
    {
        printf("your not having it anymore");
    }
}

But when this code runs firstly, when a user enters a message with no spaces, it'll get stored. But when you add spaces, the message would get chopped in half and the first bit would get stored. Secondly, when you type 'yes' (when you want to see what your loved one has sent) it crashes completely but i don't understand why. Also its not retrieving the information in the 'luvtracey.txt' file which has words in it.

I accept feedback and i just want to say thank you to those in advance who help me solve these problems.

~Neamus

  • 2
    `printf("you said %s is that true???", &reply);` --> `printf("you said %s is that true???", reply);` – yano Jun 20 '18 at 14:40
  • 2
    Possible duplicate of [Reading a string with scanf](https://stackoverflow.com/questions/5406935/reading-a-string-with-scanf) – Chris Turner Jun 20 '18 at 14:41
  • 1
    You should always check what `fopen` (and other functions) returns to make sure your file has actually been opened or not and then deal with failures – Chris Turner Jun 20 '18 at 14:43
  • There's plenty of dupes, but in short, using the `%s` format specifier, 'fscanf' will read and store until the first space in the input, leaving the remainings in the stream. So, if in input you have "Hello world. yes", you'll end up comparing "world." with {'Y', 'E', 'S'}… Try [fgets](http://en.cppreference.com/w/c/io/fgets), instead. – Bob__ Jun 20 '18 at 15:24

1 Answers1

0

if ((toupper(reply[0]) == 'Y') && (toupper(reply[1]) == 'E') ...

You can convert the string to lowercase or uppercase and strcmp, rather than checking letters one by one.

while (!feof(fpointer))
fgets(SingleLine, 150, fpointer);
puts(SingleLine);

Don't use feof. Instead check if fgets succeeds. Presumably you want to print each line in the file, so don't print the line after the loop finishes. You also need error checks to make sure the file was opened successfully. Example:

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

int main(void)
{
    char buffer[150];
    printf("enter a message: ");
    fscanf(stdin, "%s", buffer);
    printf("you said %s \n", buffer);

    FILE *fp = fopen("gift.txt", "w");
    fprintf(fp, "%s \n", buffer);
    fclose(fp);

    printf("yes or no? ");
    scanf("%s", buffer);
    for(int i = 0, len = strlen(buffer); i < len; i++)
        buffer[i] = (char)tolower(buffer[i]);
    if (strcmp(buffer, "yes") == 0)
    {
        fp = fopen("luvtracey.txt", "r");
        if(!fp)
        {
            printf("can't open...\n");
        }
        else
        {
            while(fgets(buffer, sizeof(buffer), fp))
                printf("%s", buffer);
            fclose(fp);
        }
    }
    return 0;
}
Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77
  • You cannot rely on the operation of `fscanf` unless you check the return. You must handle 3-cases, `EOF`, success, and for *matching* or *input* failure. (`EOF` can be manually generated with `Ctrl+d` (Linux) or `Ctrl+z` (windoze), but see [CTRL+Z does not generate EOF in Windows 10](http://proc-x.com/2017/06/ctrlz-does-not-generate-eof-in-windows-10/). This applies to every call to any of the `scanf` family of functions. Also `if (!fp)` simply handle the error and `return 1;` or `exit (EXIT_FAILURE);` there is no need to nest and `else`. `fscanf(stdin, "%149s", buffer);` protects bounds. – David C. Rankin Jun 20 '18 at 18:19