I want to get strings from a .txt file, reading lines that each has name and phone number. and two \t characters are between names and phone numbers.
Example:
name\t\t\tphone#
thomas jefferson\t\t054-892-5882
bill clinton\t\t054-518-6974
The code is like this;
FILE *f;
errno_t err;
treeNode *tree = NULL, temp;
char input, fileName[100];
//get file name
while (1){
printf("Enter input file name: ");
scanf_s("%s", fileName, 100);
//f = fopen(fileName, "r");
if(err = fopen_s(&f, fileName, "r"))
printf("Cannot find file!\n");
//if (f == NULL)
// printf("Cannot find file!\n");
else
break;
}
//save info into BST
fscanf_s(f, " NAME Phone #\n", 20);
while (fscanf_s(f, "%[^\t]s\t\t%[^\n]s",
temp.name, temp.phoneNo, 50, 30) != EOF)
bstInsert(tree, temp.name, temp.phoneNo);
fclose(f);
treeNode is a binary search tree struct, and bstInsert is a function to add a struct containing 2nd and 3rd parameters to a binary search tree.
after I get the name of the file with scanf_s, code stops at the fscanf_s statement, showing below on the debugger;
temp.name: invalid characters in string.
temp.phoneNo: ""
I don't know how [^\t] or [^\n] works exactly. Can anyone let me know how I can deal with this problem? Thanks in advance!
"Can anyone let me know how can I deal with this problem?" I am no fan of scanf and family, so I deal with the problem by using different methods. Following your lead of using fopen_s and scanf_s I have used the "safer" version of strtok which is strtok_s.
#include <stdio.h>
#include <string.h>
int main (void) {
FILE *f;
errno_t err;
char *pName, *pPhone;
char input[100], fileName[100];
char *next_token = NULL;
// get file name
do{
printf("Enter input file name: ");
scanf_s("%s", fileName, 100);
if(err = fopen_s(&f, fileName, "r"))
printf("Cannot find file!\n");
} while (err);
// read and process each line of the file
while(NULL != fgets(input, 100, f)) { // has trailing newline
// isolate name
pName = strtok_s(input, "\t\r\n", &next_token); // strip newline too
if (pName == NULL) // garbage trap
pName = "(Error)";
printf ("%-30s", pName);
// isolate phone number
pPhone = strtok_s(NULL, "\t\r\n", &next_token); // arg is NULL after initial call
if (pPhone == NULL)
pPhone = "(Error)";
printf ("%s", pPhone);
printf ("\n");
}
fclose(f);
return 0;
}
Program output using a file with your example data:
Enter input file name: test.txt
name phone#
thomas jefferson 054-892-5882
bill clinton 054-518-6974
Related
This question already exists:
keeps skipping prompts even after adding a space in front of %c
Closed 1 year ago.
What I'm trying to do is to replace a specific line within a txt file using C but for some reason after saying what line i want to change it just ended the exe.
void UpdateCustomerPortfolio()
{
const char path[500] = "C:\\Users\\jason\\Desktop\\College stuff\\Final assessment\\Fundimentals of programming\\Accounts\\";
int Ic[12],line;
char txt[5] =".txt",num[100];
FILE * fPtr;
FILE * fTemp;
char buffer[BUFFER_SIZE];
char newline[BUFFER_SIZE];
int count;
fflush(stdin);
printf("Input IC number: ");
gets(Ic);
strcat (path, Ic);
strcat (path, txt);
system("cls");
printf("Enter the Information that requires an update:");
printf("\n[01]First Name");
printf("\n[02]Last Name");
printf("\n[04]Home Address");
printf("\n[05]Contact Number");
printf("\n[06]Email Address\n");
scanf("%d ",line);
This is the part for some reason it keeps ending after the user enters the line they want to change. I did try using fflush(stdin); here again but it still didn't work.
printf("Replace '%d' line with: ", line);
fgets(newline, BUFFER_SIZE, stdin);
/* Open all required files */
fPtr = fopen(path, "r");
fTemp = fopen("replace.tmp", "w");
/* fopen() return NULL if unable to open file in given mode. */
if (fPtr == NULL || fTemp == NULL)
{
/* Unable to open file hence exit */
printf("\nUnable to open file.\n");
printf("Please check whether file exists and you have read/write privilege.\n");
exit(EXIT_SUCCESS);
}
/*
* Read line from source file and write to destination
* file after replacing given line.
*/
count = 0;
while ((fgets(buffer, BUFFER_SIZE, fPtr)) != NULL)
{
count++;
/* If current line is line to replace */
if (count == line)
fputs(newline, fTemp);
else
fputs(buffer, fTemp);
}
/* Close all files to release resource */
fclose(fPtr);
fclose(fTemp);
/* Delete original source file */
remove(path);
/* Rename temporary file as original file */
rename("replace.tmp", path);
printf("\nSuccessfully replaced '%d' line with '%s'.", line, newline);
}
Your scanf should read scanf("%d", &line);
So my problem is that I have a text file with names and services that they ordered. I need to search a file for a given name and then output a line on which that name is located. Here's my code, although it outputs the content of a line and not the actual line
printf("What is the customer's name\n");
scanf("%s", &name);
f = fopen("C:\\customer_info.txt", "r");
while (fgets(line, sizeof(line), f) != NULL)
{
if (strstr(line, name) != NULL)
{
printf("%s", line);
}
}
Try this way:
#include <stdio.h>
#include <string.h>
#define MAX 100
int main(void) {
char word_to_find[MAX], line[MAX];
FILE *fp = fopen("customer_info.txt", "r");
FILE *fp_write = fopen("customers_new_added.txt", "a");
unsigned short FLAG_FOUND = 0;
if (!fp) {
printf("Failed to open the file.\n");
return -1;
}
printf("Enter a customer name to find: ");
fgets(word_to_find, MAX, stdin);
while (fgets(line, sizeof(line), fp) != NULL) { // reading till NULL of File
if (strstr(line, word_to_find) != NULL) { // finding till NULL of Line
printf("%s", line);
fprintf(fp_write, "%s", line); // writing the entire line into the file
FLAG_FOUND = 1; // found something in the line?
}
}
if (!FLAG_FOUND) // if zero
printf("Sorry, no matches were found...\n");
fclose(fp_write);
fclose(fp);
return 0;
}
Explanation
The statement:
strstr(line, word_to_find) != NULL
Will only become NULL when it reaches NULL, in other words, the customer name should be given in the last position of lines.
My customer_info.txt is as follows:
PRICE SERVICE CUSTOMER_NAME
=========================================
1250.00 Premium John_Doe
750.00 Pro Pack Lorem_Ipsum
1800.00 Grand Johnny_Doe
The program works like:
$ g++ -o pro pro.cpp; ./pro
Enter a customer name to find: John_Doe
1250.00 Premium John_Doe // LET LINE_X
The mentioned LINE_X will be written into customers_new_added.txt (creates if doesn't exists).
customers_new_added.txt is as follows now:
1250.00 Premium John_Doe
The end of file must contain a new line or the last line will not be read.
I'm trying to get two words in a string and I don't know how I can do it. I tried but if in a text file I have 'name Penny Marie' it gives me :name Penny. How can I get Penny Marie in s1? Thank you
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("Hello world!\n");
char s[50];
char s1[20];
FILE* fp = fopen("file.txt", "rt");
if (fp == NULL)
return 0;
fscanf(fp,"%s %s",s,s1);
{
printf("%s\n",s);
printf("%s",s1);
}
fclose(fp);
return 0;
}
Change the fscanf format, just tell it to not stop reading until new line:
fscanf(fp,"%s %[^\n]s",s,s1);
You shall use fgets.
Or you can try to do this :
fscanf(fp,"%s %s %s", s0, s, s1);
{
printf("%s\n",s);
printf("%s",s1);
}
and declare s0 as a void*
The other answers address adjustments to your fscanf call specific to your stated need. (Although fscanf() is not generally the best way to do what you are asking.) Your question is specific about getting 2 words, Penny & Marie, from a line in a file that contains: name Penny Marie. And as asked in comments, what if the file contains more than 1 line that needs to be parsed, or the name strings contain a variable number of names. Generally, the following functions and techniques are more suitable and are more commonly used to read content from a file and parse its content into strings:
fopen() and its arguments.
fgets()
strtok() (or strtok_r())
How to determine count of lines in a file (useful for creating an array of strings)
How to read lines of file into array of strings.
Deploying these techniques and functions can be adapted in many ways to parse content from files. To illustrate, a small example using these techniques is implemented below that will handle your stated needs, including multiple lines per file and variable numbers of names in each line.
Given File: names.txt in local directory:
name Penny Marie
name Jerry Smith
name Anthony James
name William Begoin
name Billy Jay Smith
name Jill Garner
name Cyndi Elm
name Bill Jones
name Ella Fitz Bella Jay
name Jerry
The following reads a file to characterize its contents in terms of number of lines, and longest line, creates an array of strings then populates each string in the array with names in the file, regardless the number of parts of the name.
int main(void)
{
// get count of lines in file:
int longest=0, i;
int count = count_of_lines(".\\names.txt", &longest);
// create array of strings with information from above
char names[count][longest+2]; // +2 - newline and NULL
char temp[longest+2];
char *tok;
FILE *fp = fopen(".\\names.txt", "r");
if(fp)
{
for(i=0;i<count;i++)
{
if(fgets(temp, longest+2, fp))// read next line
{
tok = strtok(temp, " \n"); // throw away "name" and space
if(tok)
{
tok = strtok(NULL, " \n");//capture first name of line.
if(tok)
{
strcpy(names[i], tok); // write first name element to string.
tok = strtok(NULL, " \n");
while(tok) // continue until all name elements in line are read
{ //concatenate remaining name elements
strcat(names[i], " ");// add space between name elements
strcat(names[i], tok);// next name element
tok = strtok(NULL, " \n");
}
}
}
}
}
}
return 0;
}
// returns count, and passes back longest
int count_of_lines(char *filename, int *longest)
{
int count = 0;
int len=0, lenKeep=0;
int c;
FILE *fp = fopen(filename, "r");
if(fp)
{
c = getc(fp);
while(c != EOF)
{
if(c != '\n')
{
len++;
}
else
{
lenKeep = (len < lenKeep) ? lenKeep : len;
len = 0;
count++;
}
c = getc(fp);
}
fclose(fp);
*longest = lenKeep;
}
return count;
}
Change your fscanf line to fscanf(fp, "%s %s %s", s, s1, s2).
Then you can printf your s1 and s2 variables to get "Penny" and "Marie".
Try the function fgets
fp = fopen("file.txt" , "r");
if(fp == NULL) {
perror("Error opening file");
return(-1);
}
if( fgets (str, 60, fp)!=NULL ) {
/* writing content to stdout */
puts(str);
}
fclose(fp);
In the above piece of code it will write out the content with the maximum of 60 characters. You can make that part dynamic with str(len) if I'm not mistaken.
int main()
{
FILE *infile;
FILE *infile2;
char input[255],input2[255];
int status1, status2;
infile = fopen("test.txt", "r");
infile2 = fopen("test2.txt", "r");
if(infile == NULL)
{
printf("Can not open file 1!\n");
}
else if(infile2 == NULL)
{
printf("Can not open file 2!\n");
}
else
{
do
{
status1 = fscanf(infile, "%s", &input);
status2 = fscanf(infile2, "%s", &input2);
printf("File 1: %s\n File 2: %s\n", input, input2);
}while(status1 != -1 || status2 != -1);
}
fclose(infile);
fclose(infile2);
return 0;
}
My output looks like this:
Output
I would like to print out file 1 in one line not word by word. The same goes for file2. I'm kinda new to C so I'm stuck.
If you would like to read the entire line, use fgets function instead of fscanf:
char *status1, *status2;
.
.
.
do {
status1 = fgets(input, sizeof(input), infile);
status2 = fgets(input2, sizeof(input2), infile2);
printf("File 1: %s File 2: %s", input, input2);
} while (status1 || status2);
Note how printf no longer uses \n. This is because fgets keeps \n from the file inside your input string.
I made the changes to the code and it works, but another question. If i wanted to compare the files and write out the differnce to a new file like this:
File1: My name is Knut
File2: My name is KnutAndre
File3: Andre (This is the differnce between the files).
My teacher told me to use strcmp and then get the output into a new file, but i dont quite understand him.. Does anyone have some tips that i could try out?
This is how my code look so far:
int main()
{
FILE *infile;
FILE *infile2;
FILE *outfile3;
char input[255],input2[255];
char status1, status2;
infile = fopen("test.txt", "r");
infile2 = fopen("test2.txt", "r");
if(infile == NULL)
{
printf("Can not open file 1!\n");
}
else if(infile2 == NULL)
{
printf("Can not open file 2!\n");
}
else
{
do
{
status1 = fgets(input, sizeof(input), infile);
status2 = fgets(input2, sizeof(input2), infile2);
if(status1 != 0){
printf("File 1: %s\n\nFile 2: %s\n\n", input, input2);
int result = strcmp(input, input2);
printf("\nResult = %d\n\n", result);
}
}
while(status1 || status2);
}
fclose(infile);
fclose(infile2);
return 0;
}
When you are using the fscanf it will only read the characters until the non white space character occurs. When you need to get the input as whole line then you have to use fgets().
From the man page of fgets().
fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an
EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null byte ('\0') is stored after the last character
in the buffer.
So you have to use like this.
fgets(input,255,infile);
fgets(input2,255,infile2);
While checking condition,
while(input != NULL || input2 != NULL);
In my school, we make a get_next_line function, who takes a file descriptor and a pointer to a string in parameter.
you can take a look here : https://github.com/juschaef/libtowel/search?utf8=%E2%9C%93&q=get+next+line
So i've been given an exercise to work on: Have the user input a number and the program will display the line of text associated with that line for example
Password
abcdefg
Star_wars
jedi
Weapon
Planet
long
nail
car
fast
cover
machine
My_little
Alone
Love
Ghast
Input 3: Output: Star_wars
Now i have been given a program to solve this, however it uses the function getline() , which doesn't complie on DEV C++.
#include <stdio.h>
int main(void)
{
int end = 1, bytes = 512, loop = 0, line = 0;
char *str = NULL;
FILE *fd = fopen("Student passwords.txt", "r");
if (fd == NULL) {
printf("Failed to open file\n");
return -1;
}
printf("Enter the line number to read : ");
scanf("%d", &line);
do {
getline(&str, &bytes, fd);
loop++;
if (loop == line)
end = 0;
}while(end);
printf("\nLine-%d: %s\n", line, str);
fclose(fd);
}
All i need is to know how to do this, in a simple program without the use of getline()
Thanks
Edit: I also don't want to download software to make this work
use fgets instead of getline.
#include <stdio.h>
int main(void){
int end, loop, line;
char str[512];
FILE *fd = fopen("data.txt", "r");
if (fd == NULL) {
printf("Failed to open file\n");
return -1;
}
printf("Enter the line number to read : ");
scanf("%d", &line);
for(end = loop = 0;loop<line;++loop){
if(0==fgets(str, sizeof(str), fd)){//include '\n'
end = 1;//can't input (EOF)
break;
}
}
if(!end)
printf("\nLine-%d: %s\n", line, str);
fclose(fd);
return 0;
}
You have wrote:
char *str = NULL;
and you used it without initializing:
getline(&str, &bytes, fd);
first you must initialize it:
char *str=(char*)malloc(SIZEOFSTR);
you can add this part in your program instead of your do-while loop. You will be using fscanf() whose arguments are the file pointer, specifier of data type and the variable you want to store.
printf("Enter the line number to read : ");
scanf("%d", &line);
while(line--) {
fscanf(fd,"%s",str);
}
printf("\nLine-%d:%s\n",line,str);