I a trying to take file name as argument and write strings using loop until user enter "-1".
problem 1: writing is not happening in text file and always shows empty
problem 2: cannot compare input -1 and "-1" . Always runs the else statements.
Note: I also tried fputs but it did not work that time either.
FILE *fp = fopen(argv[1], "a");
//fseek(fp, 0, SEEK_END);
char str[100];
printf("enter string\n");
bool flag = true;
while (flag == true) {
//printf("\nEnter data to append: ");
fflush(stdin);
fgets(str, 100, stdin);
if (strcmp(str, "-1") == 0) {
break;
} else {
fprintf(fp, "%s", str);
printf("Text written in file: %s\n", str);
}
}
fclose(fp);
Writing don't happen because of strcmp, I'm showing you my version of this with atoi.
#include <stdio.h>
#include <stdlib.h>
#define buffer 128
int main(int argc, char *argv[])
{
char str[buffer];
int flag = 1;
FILE *fp = fopen(argv[1], "w+"); //I prefer using write mode and not append
if(fp==NULL)
{
printf("Error opening file.\n"); //here you control if the file is opening correctly
exit(EXIT_FAILURE);
}
while(flag) //you don't need to write while(flag==true) (that's not wrong)
{
printf("Insert string: ");
scanf("%s", str);
if(atoi(str)==1) //the function strcmp as you wrote it will break after the
break; //first cicle, use atoi, it returns 1 if the string is a number
fprintf(fp, "%s\n", str); //the \n is to get the next string on the next row
}
fclose(fp);
return 0;
}
If you want to make it work with strcmp your if statement should be if(strcmp(str, "-1\n")) because fgets reads also the \n character.
Because fget() reads new line character.
So once you do comparation, It looks like:
strcmp("-1\n", "-1");
or
strcmp("-1\n\r", "-1");
You will never break the loop.
To remove newline character, let try:
strtok(str, "\n");
or
strtok(str, "\r\n");
Related
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
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;
}
When I execute my code below. It waits for my input for entering a file name. But it doesn't wait for me to enter a filename, but rather just skips it to the _getch() part of it. I'm unable to add a sentence.
Code not working:
#include <stdio.h>
main() {
FILE *fp;
char fnamer[100] = ""; //Storing File Path/Name of Image to Display
printf("\n\nPlease Enter the Full Path of the Image file you want to view: \n");
scanf("%s", &fnamer);
fp = fopen(fnamer, "w");
if (fp == NULL)
{
printf("\n%s\" File NOT FOUND!", fnamer);
}
char c[1000];
printf("Enter a sentence:\n");
gets(c);
fprintf(fp, "%s", c);
fclose(fp);
_getch();
}
Code that works and waits for entering a sentence:
#include <stdio.h>
#include <stdlib.h> /* For exit() function */
int main()
{
char c[1000];
FILE *fptr;
fptr = fopen("program.txt", "w");
if (fptr == NULL){
printf("Error!");
exit(1);
}
printf("Enter a sentence:\n");
gets(c);
fprintf(fptr, "%s", c);
fclose(fptr);
return 0;
}
Both are so similar right there in the end for the prompt asking for a sentence. It doesn't make sense.
you have to flush your input after using scanf.
put a getchar() after every scanf
You are encountering a very common problem when using stdin to receive input, which is after your first scanf call there is a dangling \n character which gets stuck in the buffer from the enter key. To clear this buffer in a portable easy way, add something like
char c;
while ( (c = getchar()) != '\n' && c != EOF ) { }
This simply initializes a character, and then calls get char as many times as needed until it reaches '\n' or 'EOF', which is immediately in your case.
tl;dr :
Your buffer looks like this
hello.txt\n <-- "comes from the enter key"
and when you try to use get(c) it takes the \n as the next enter key.
The rule is never mix scanf and [f]gets. scanf stops before the next unused character, generaly a blank, and the end of line is composed of blank characters.
You could try to put a dummy fgets between the last scanf and the first real fgets. That will ensure that you are now positionned on a beginning of line before reading. Alternatively, you could read everything in lines with fgets, and parse the lines with sscanf. That is what I prefere as soon as I want my input to be line oriented. And always control return values of input functions, it will avoid a progam suddenly going mad without any indication simply because one input gave an ignored error.
And last and not least: never use gets but only fgets, the former is for decades in the hall of shame as the cause of uncountable buffer overflows
Code could become:
#include <stdio.h>
#include <string.h>
main() {
FILE *fp;
char fnamer[100] = ""; //Storing File Path/Name of Image to Display
char c[1000], *ix;
int cr;
printf("\n\nPlease Enter the Full Path of the Image file you want to view: \n");
cr = scanf("%s", &fnamer);
if (cr != 1) {
// process error or abort with message
}
fp = fopen(fnamer, "w");
if (fp == NULL)
{
printf("\n%s\" File NOT FOUND!", fnamer);
return 1; // do not proceed after a fatal error!
}
for(;;) { // read until a newline in input
ix = fgets(c, sizeof(c), stdin);
if (ix == NULL) {
// end of input: abort
}
if (strcspn(c, "\n") < strlen(c)) break;
}
printf("Enter a sentence:\n");
ix = fgets(c, sizeof(c), stdin);
c[strcspn(c, "\n")] = '\0'; // remove end of line to get same data as gets
fprintf(fp, "%s", c);
fclose(fp);
_getch();
}
main() {
FILE *fp;
char fnamer[100]=""; //Storing File Path/Name of Image to Display
printf("\n\nPlease Enter the Full Path of the Image file you want to view: \n");
fgets ( fnamer,100,stdin); //fgets(name, sizeof(name), stdin);
fp=fopen(fnamer,"w");
if(fp==NULL)
{
printf("\n%s\" File NOT FOUND!",fnamer);
getch();
exit(1);
}
}
I Think best way to do,use fgets insted of scanf,Because
fgets() can read any open file, but scanf() only reads standard input(user given).
fgets() reads a line of text from a file; scanf() can be used for that but also handles conversions
from string to built in numeric types
I am writing a menu system in C, the code works correctly but for some reason the first first time the while loop is entered for the menu it skips the getchar() command and runs through the while loop again, but the second time round it works?
Any ideas as to why it does this?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "structs.h"
int main(void)
{
FILE *fp = NULL;
char fileName[25], line[200], userInput = ' ';
int len;
while (fp == NULL)
{
printf("Enter The File To Load In: \n");
scanf("%s", fileName); // Ask User For File Name
fp = fopen(fileName, "r"); // Open File To Read
if (fp == NULL)
{
perror("Error While Loading File\n");
}
}
while (userInput != 'g')
{
printf(" |User System|\n");
printf("A) Save Current Data To A File\n");
printf("B) Enter Details\n");
printf("C) View Details\n");
printf("D) Amend Details\n");
printf("E) Search by Award Title\n");
printf("F) Search by Surname\n");
printf("G) Shut Down\n");
userInput = getchar();
if (userInput == 'c')
{
fgets(line, 200, fp);
len = strlen(line);
printf("%s", line);
userInput = getchar();
}
}
}
After 'scanf' use
getchar();
to consume extra newline. As 'scanf' can not discard newline, first iteration of 'getchar();' take the newline.
So you shold place getchar() after scanf as to consume extra newline('\n')
scanf("%s", fileName);
getchar();
It's better to use 'fgets' instead of scanf as file name may have space.
You can use 'fgets()' as
fgets(fileName, sizeof(fileName), stdin);
fileName[strlen(fileName)-1] = 0; //Replace newline with '\0' character
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
struct info
{
char name[15];
char surname[15];
char gender[15];
char education[15];
} sem;
FILE *fp=NULL;
int i, a;
char tmp[256] = {0x0};
while(1)
{
printf("Enter the value\n");
scanf("%d", &a);
if((fp = fopen("info.txt", "r")) != NULL)
{
switch(a)
{
case 0:
exit(0);
case 1:
for(i=0;!feof(fp);i++)
{
fscanf(fp, "%s %s %s %s", sem.name, sem.surname, sem.gender, sem.education);
printf("%s, %s, %s, %s\n",sem.name,sem.surname,sem.gender,sem.education);
}
break;
case 2:
while (fgets(tmp, sizeof(tmp), fp) != NULL)
{
if (strstr(tmp, "bachelors"))
{
/* Code works fine until this part */
fprintf(fp, "\n%s %s %s %s", sem.name, sem.surname, sem.gender, sem.education);
}
}
break;
default: printf("Default statement");
}
fclose(fp);
}
}
}
If anyone could point me out what im doing wrong, id be very greatful, I added a comment where code runs in to a problem and doesnt display anything. Basicly i have txt file. Program if user so desires needs to find lines in the file where "bachelor" is typed and give me back all of those lines.
You are opening your file in read mode (fp = fopen("info.txt", "r")) and trying to write in it using fprintf() which is not possible.
Use fp = fopen("info.txt", "r+") i.e read and write mode.
If you want to compare strings, you will have to use strcmp(), not an undefined function like "strstr". Also, strcmp returns 0 if two strings have same value. So you also have to check that the return value of strcmp() is zero or not.
Also as I replied to your question yesterday, fprintf() method appends the characters that you've passed as arguments to file. So, in your code, when you find string "bachelor", you just add same line at the end of the file. If you want to see those data in console, you can use printf() method.
I have some demo code that wants the user to input a filename and the mode. The book is suggesting the dreaded gets(); function for input, which I refuse to use, so I tried to grab my input with fgets(). When I used fgets() I specified my input stream as 'stdin', however the code will not work. The code WILL work with gets(), however. I assume that the problem with my implementation of fgets() is the 'stdin' stream type. Is that why my fgets() will not work with this program? If so, what input stream type should I use? Here is the program:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *fp;
char ch, filename[40], mode[4];
while(1)
{
printf("\nEnter a filename: "); //This is where fgets/gets conflict is
//fgets(filename, 30, stdin); //I commented out the fgets()
gets(filename);
printf("\nEnter a mode (max 3 characters):");
//fgets(mode, 4, stdin); //fgets again
gets(mode);
//Try to open the file
if((fp = fopen(filename, mode)) != NULL)
{
printf("\nSuccessful opening %s in mode %s.\n",
filename, mode);
fclose(fp);
puts("Enter x to exit, any other to continue.");
if((ch = getc(stdin)) == 'x')
{
break;
}else{
continue;
}
}else
{
fprintf(stderr, "\nError opening file %s in mode %s.\n",
filename, mode);
puts("Enter x to exit, any other to try again.");
if((ch = getc(stdin)) == 'x')
{
break;
}else{
continue;
}
}
}
return 0;
}
Thanks in advance all. This program was from "Teach Yourself C in 21 Days" by B. Jones.
Well done on not wanting to use gets(); that is absolutely the correct way to go.
The error opening the file arises from the fact that fgets() keeps the newline and gets() does not. When you try to open the file name with the newline, the file is not found.