The following function creates a new text file and allows the user to input text to be saved to the file. The main issues that I'm having troubles fixing is 1)allowing spaces between words 2)hitting enter saves the text, instead of going to a new line.
void new_file(void)
{
char c[10000];
char file[10000];
int words;
printf("Enter the name of the file\n");
scanf("%123s",file);
strcat(file,".txt");
FILE * pf;
pf = fopen(file, "w" );
if (!pf)
fprintf( stderr, "I couldn't open the file.\n" );
else
{
printf("Enter text to be saved\n");
scanf("%s", c);
fprintf(pf, "%s", c);
}
fclose(pf); // close file
printf("\n\nReturning to main menu...\n\n");
}
Use fgets() instead of scanf() to get the input text from the user.
To do so replace this line
scanf("%s", c);
with the following code:
if (NULL != fgets(c, sizeof(c), stdin))
{
fprintf(pf, "%s", c);
}
else
{
if (0 != ferror(stdin))
{
fprintf(stderr, "An error occured while reading from stdin\n");
}
else
{
fprintf(stderr, "EOF was reached while trying to read from stdin\n");
}
}
To allow the user to read in more then one line put a loop around the code above. Doing so you need to define a condition which tells the program to stop looping:
The following example stops reading in lines when entering a single dot "." and pressing return:
do
{
if (NULL != fgets(c, sizeof(c), stdin))
{
if (0 == strcmp(c, ".\n")) /* Might be necessary to use ".\r\n" if on windows. */
{
break;
}
fprintf(pf, "%s", c);
}
else
{
if (0 != ferror(stdin))
{
fprintf(stderr, "An error occured while reading from stdin\n");
}
else
{
fprintf(stderr, "EOF was reached while trying to read from stdin\n");
}
break;
}
} while (1);
Related
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");
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;
}
I'm writing a program that allows multiple users to create, save, and load data to files. I'm running into an issue where I can't find seem to figure out a logic that doesn't allow users to create duplicate file names.
Here is the important working part of my code thus far, but where my issues are. The variable user is assigned at the launch of my program where the user must enter their username and password.
else if (selection == 6)
{
int i;
int d;
printf("Please enter a file name: ");
scanf("%s", filename);
newFile = fopen(filename, "a+");
Record = fopen("records.txt", "a+");
fprintf(Record, "%s %s\n", user, filename);
for (i = 0; i < icount; i++)
{
fprintf(newFile, "%d ", ints[i]);
}
for (d = 0; d < dcount; d++)
{
fprintf(newFile, "%lf ", doubles[d]);
}
fclose(Record);
fclose(newFile);
}
else if (selection == 7)
{
printf("Please enter a file name: ");
scanf("%s", filename);
Record = fopen("records.txt", "a+");
while (fscanf(Record, "%s %s", curuser, curfile) != EOF)
{
if (strcmp(user, curuser) == 0 && strcmp(filename, curfile) == 0)
{
int c;
//fopen(newFile, "a+");
newFile = fopen(filename, "a+");
if (newFile) {
while ((c = getc(newFile)) != EOF)
{
putchar(c);
}
fclose(newFile);
break;
}
}
else
{
printf("You don't have access to this file.\n");
break;
}
}
}
Somewhere in selection 6, I'm trying to say in code, "Okay user, enter a file, unless the name already exists." What I tried was
while (fscanf(Record, "%s %s", curuser, curfile) != EOF)
{
if (strcmp(curfile, filename) == 0)
{
break;
}
else
{
fprintf(Record, "%s %s\n", user, filename);
fclose(Record);
}
}
and I'm unable to figure out why this won't work. I tried placing this code right below Record file declaration.
I think the issue may be that when the record file is empty, the != EOF line is causing it to break, but I also can't figure out a way to initially get one user and filename in the record before probing the rest of the users for their filenames. Any guidance in the right direction would be appreciated!
I think you can solve your problem by cutting the while loop in several parts:
do the fscanf
check for end of file
check for "user found"
And finally,
write user if not previously in file.
I would have written something like:
int record_found = 0;
int scanf_res;
while (1)
{
/* do the fscanf */
scanf_res = fscanf(Record, "%s %s", curuser, curfile);
/* test for end of file */
if (EOF == scanf_res)
{
/* end of file reached */
break;
}
/* if fscanf has mado 2 conversion AND
filename is curfile */
if ((2 == scanf_res) && (strcmp(curfile, filename) == 0))
{
record_found = 1;
break;
}
}
if (!record_found)
{
/* add user if needed */
fprintf(Record, "%s %s\n", user, filename);
}
/* and close file in all cases */
fclose(Record);
In this program, I am attempting to read a name and their GPA from a file. The first name is Audrey, then a white space, and then 3.6.
The second line is Oakley, then a white space, and 3.5.
int main()
{
FILE * fPtr;
FILE * fPtr2;
char x[10] = { "Oakley " };
double y;
int z;
fPtr = fopen("data.txt", "r");
if (fPtr == NULL) // open failure
puts("File open for read failed");
else
{
while (scanf("%d", &z) != EOF)
{
fscanf(fPtr, "%s", x);
fscanf(fPtr, "%lf", &y);
fprintf(stdout, "Value read = %s\n", x);
fprintf(stdout, "GPA = %lf \n", y);
}
}
fclose(fPtr);
system("pause");
return 0;
}
So, I tried this once before and it worked. In that attempt, "x[10] = Audrey" and this was the first name in the list. It worked, and the fscanf gave me her GPA. The second time, I tried scanning for Oakley and I still get Audrey, but when I remove that line I get a really large negative number.
I used fscanf because it tokenizes around whitespace, so my theory is that if the cursor gets to the proper name then it will read the next number and that will be the GPA? Right? How do I get it to search for Oakley?
You need check scanf for any errors, which could happen because the input file does not match the format you specified. Try these changes:
char user[100];
while (scanf("%s", user) == 1) {
while (fscanf(fPtr, "%s %lf", x, &y) == 2)
{
if (strcmp(user, x) == 0) {
fprintf(stdout, "GPA for %s is %lf \n", user, y);
break;
}
}
rewind(fPtr);
}
Also, fPtr2 is is uninitialized in your code, remove the line fclose(fPtr2).
The program works when the edit is alone and it also works when the read is alone :
printf("Enter the name of file you wish to edit:\n");
gets(file_name); //file_name = input
file = fopen(file_name,"w"); // write mode
if( file == NULL ) //If file couldn't be opened
{
perror("Error while opening the file!\n");
exit(EXIT_FAILURE);
}
printf("Enter name: \n"); scanf("%s",name1);
printf("Enter second name if applicable: \n"); scanf("%s",name2);
printf("Enter grade: \n"); scanf("%s",grade);
fprintf(file, "%s%s%s\t%s%s%s", name1, " ", name2, "=", " ", grade);
fclose(file);
printf("File write was successful\n");
And
printf("Enter the name of file you wish to see:\n");
gets(file_name); //file_name = input
file = fopen(file_name,"r"); // read mode
if( file == NULL ) //If file couldn't be opened
{
perror("Error while opening the file!\n");
exit(EXIT_FAILURE);
}
printf("The contents of %s file are:\n", file_name);
while( ( character = fgetc(file) ) != EOF /*EOF = End Of File*/)
printf("%c",character); //print c (character)
fclose(file); //remove the file from RAM
However when they are put together with an if the program crashes as soon as 1 or 2 is inputted into the first section:
printf("Edit or Read file? (1 for edit, 2 or read)\n"); scanf("%s",RW);
Here is the whole code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char character, file_name[25];
int RW;
const char *quit;
FILE *file; //"file" stores file stream
char data [100000];
char name1 [100000];
char name2 [100000];
char grade [100000];
printf("Edit or Read file? (1 for edit, 2 or read)\n"); scanf("%s",RW);
if (RW == 1)
{
printf("Enter the name of file you wish to see:\n");
gets(file_name); //file_name = input
file = fopen(file_name,"r"); // read mode
if( file == NULL ) //If file couldn't be opened
{
perror("Error while opening the file!\n");
exit(EXIT_FAILURE);
}
printf("The contents of %s file are:\n", file_name);
while( ( character = fgetc(file) ) != EOF /*EOF = End Of File*/)
printf("%c",character); //print c (character)
fclose(file); //remove the file from RAM
} else if ( RW == 2) {
printf("Enter the name of file you wish to edit:\n");
gets(file_name); //file_name = input
file = fopen(file_name,"w"); // write mode
if( file == NULL ) //If file couldn't be opened
{
perror("Error while opening the file!\n");
exit(EXIT_FAILURE);
}
printf("Enter name: \n"); scanf("%s",name1);
printf("Enter second name if applicable: \n"); scanf("%s",name2);
printf("Enter grade: \n"); scanf("%s",grade);
fprintf(file, "%s%s%s\t%s%s%s", name1, " ", name2, "=", " ", grade);
fclose(file);
printf("File write was successful\n");
}
printf(" \n");
printf("Close window?\n"); scanf("%s",quit);
if (quit == "y")
{
printf("Bye!\n");
}
return (0);
}
the posted program crashes because of this line:
scanf("%s",RW);
the variable RW is declared as an int.
The call to scanf() is expecting a pointer to an char array.
so the code is trying to tread RW as a pointer, and followed that pointer (which contains what ever trash was on the stack at the location of RW. That is what is causing the crash.
Suggest writing the statement as:
scanf("%u",&RW);
As BLUEPIXY said:
scanf("%s",RW); --> scanf("%d%*c", &RW);
const char *quit; --> char quit; ... scanf("%s",quit); if(quit == "y") --> scanf(" %c", &quit); if(quit == 'y')
These changes meant that there were no problems with the variables.