I trying to open a simple txt file in C, like the image bellow.
list example
The input text :
Name Sex Age Dad Mom
Gabriel M 58 George Claire
Louise F 44
Pablo M 19 David Maria
My doubt is, how can i make to identify the blank spaces in the list and jump correctly to another lines.
Here is my code:
#include <stdio.h>
int main() {
FILE *cfPtr;
if ((cfPtr = fopen("clients.txt", "r")) == NULL) {
puts("The file can't be open");
} else {
char name[20];
char sex[4];
int age;
char dad[20];
char mom[20];
char line[300];
printf("%-10s%-10s%-10s%-10s%-10s\n","Name","Sex","Age","Dad","Mom");
fgets(line,300,cfPtr);
fscanf(cfPtr,"%10s%10s%d%12s%12s",name,sex,&age,dad,mom);
while (!feof(cfPtr)) {
printf("%-10s%-10s%d%12s%12s\n",name,sex,age,dad,mom);
fscanf(cfPtr,"%19s%3s%d%12s%12s",name,sex,&age,dad,mom);
}
fclose(cfPtr);
}
return 0;
}
It works fine if I fill in all the spaces...
printf("%-10s%-10s%d%12s%12s\n",name,sex,age,dad,mom);
fscanf(cfPtr,"%19s%3s%d%12s%12s",name,sex,&age,dad,mom);
Change the order to read first, print later.
Ideally the data in your file should be separated by comma, tab, or some other character. If data is in fixed columns, then read everything as text (including integers) then convert the integer to text later.
Also check the return value for fscanf, if the result is not 5 then some fields were missing.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
FILE *cfPtr = fopen("clients.txt", "r");
if(cfPtr == NULL)
{
puts("The file can't be open");
return 0;
}
char name[11], sex[11], dad[11], mom[11], line[300];
int age;
fgets(line, sizeof(line), cfPtr); //skip the first line
while(fgets(line, sizeof(line), cfPtr))
{
if(5 == sscanf(line, "%10s%10s%10d%10s%10s", name, sex, &age, dad, mom))
printf("%s, %s, %d, %s, %s\n", name, sex, age, dad, mom);
}
fclose(cfPtr);
return 0;
}
Edit, changed sscan format to read integer directly, changed buffer allocation to 11 which is all that's needed.
Related
In a file, words like this are written:
Name
Surname
Age
Job
Telephone
James
Cooper
26
engineer
6545654565
Bob
Allen
22
doctor
5656555655
....
I want to print specific parts from these lines (for examples only names). I have tried this code but I can only print 1 line I want. (I print only James but I want to print all names: James, Bob,...).
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
int lineNumber;
static const char filename[] = "hayat.txt";
for(lineNumber=5;lineNumber<20;lineNumber+5);
FILE *file = fopen(filename, "r");
int count = 0;
if ( file != NULL )
{
char line[256];
while (fgets(line, sizeof line, file) != NULL)
{
if (count == lineNumber)
{
printf("\n %s ", line);
fclose(file);
return 0;
}
else
{
count++;
}
}
fclose(file);
}
return 0;
}
How can I do this?
I tried to make it work writing the code the most similar to the code in the question. This might not be the optimal solution but should work.
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#define TAMLINE 256
int main(void){
int lineNumber, count=0;
static const char filename[] = "hayat.txt";
FILE *file = fopen(filename, "r");
if ( file != NULL ){
char line[TAMLINE];
/* //use this if you want to skip first 5 lines
for(int i=0;i<5;i++){
fgets(line, TAMLINE, file)
}
*/
while (fgets(line, TAMLINE, file) != NULL){
count ++;
//only print 1st line, 6th line 11 line.. ie lines with names
if (count%5 == 1){
printf("%s", line);
}
}
fclose(file);
}
return 0;
}
You only print once because that's exactly what are telling the programm to do
if linenumber == count ... print
else count++
will always print only one line.
As for how to print difference categories, you either find similarities ( like some Objects and all names start with a capital letter and no number) or you specify them in an array - which probably would not be what you would like.
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.
I am trying to simply read in a basic text file, split each line into separate strings and rearrange/copy them onto a new text file. Is there any simple way to split and identify these strings to be added to a new file at the end of processing the lines?
My code so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE *pFileCust
fPointer = fopen("Athletes.txt", "r");
char singleLine[150];
while (!feof(pFileCust)){
fscanf(singleLine, 150);
int id, name, sport;
fprintf(%d[0,6], %s[8,15], %s[16,22], id, name, sport);
}
fclose(fPointer);
return 0;
}
Example Text File to be read into the program:
88888 John Doe Tennis
99999 Jane Smith Softball
Example Output that I am trying to achieve.
Tennis 88888 John Doe
Softball 99999 Jane Smith
Each line in your file corresponds to a record. Each series of consecutive non-whitespace characters corresponds to a field in the current record. Accordingly,
/* getrecord: read next record on fp */
char *getrecord(FILE *fp)
{
assert(fp);
char *line = malloc(MAXLINE);
if (line != NULL)
if (fgets(line, MAXLINE, fp) != NULL)
return line;
return NULL;
}
/* getfield: read next field in record */
char *getfield(const char *record, int *pos)
{
assert(record && pos);
char *record;
int ret;
if ((record = malloc(MAXRECORD)) != NULL) {
ret = sscanf(record + *pos, "%s", record);
if (ret == 1)
return record;
}
return NULL;
}
While each function does not appear to do much work, separating your business logic from record/field reading has real benefits. It allows extensibility (for example you can add error handling to these routines). You can also make more sense of your code. Now you can write your main function which will use this pair of calls.
Here is a simple adaptation of your code that (a) compiles, and (b) generates the output that you desire.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE *pFileCust = fopen("Athletes.txt", "r");
char first_name[100], last_name[100], sport[100];
int id;
while (fscanf(pFileCust, "%d %s %s %s", &id, first_name, last_name, sport) != EOF) {
printf("%s %d %s %s\n", sport, id, first_name, last_name);
}
fclose(pFileCust);
return 0;
}
One of the key things your app was missing was anything assigning values to your variables; your fscanf was not doing anything (if it even compiled). fscanf is not a very GOOD way to parse text, it's not very robust. But for the principle of understanding how variables are assigned, please look carefully at that, and in particular understand why the id has an ampersand in front of it. Also, make sure you understand why I used both a first name and a last name.
As the title indicates I'm trying to make a program that verifies if a word is in a file and prints the number of the line and the line itself. The exercise tells us to use the function strstr.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DIM_WORDS 1000
int main(void)
{
char word[DIM_WORDS]={'\0'};
char textname[DIM_WORDS]={'\0'};
char stringtoread[DIM_WORDS]={'\0'};
char line[DIM_WORDS]={'\0'};
char* verify;
FILE* fp=NULL;
int ret=0 , num=0;
do{
printf("Introduza o nome do ficheiro e a palavra a procurar\n");
// Lê ambas as informações e guarda-as numa string
fgets(stringtoread, DIM_WORDS, stdin);
// Separa as duas informações em 2 strings
ret=sscanf(stringtoread, "%s %s", textname, word);
}while(ret!=2);
fp=fopen(textname, "r");
if(fp==NULL)
{
printf("Error: That file doesn't exist or could not be open\n");
exit(EXIT_FAILURE);
}
while(fgets(line, sizeof(line), fp))
{
verify = strstr(word, line);
if(verify!=NULL)
{
printf("The word was encountered in line %d\n", num);
printf("%s", line);
}
num++;
}
fclose(fp);
return EXIT_SUCCESS;
}#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DIM_WORDS 1000
int main(void)
{
char word[DIM_WORDS]={'\0'};
char textname[DIM_WORDS]={'\0'};
char stringtoread[DIM_WORDS]={'\0'};
char line[DIM_WORDS]={'\0'};
char* verify;
FILE* fp=NULL;
int ret=0 , num=0;
do{
printf("Introduza o nome do ficheiro e a palavra a procurar\n");
fgets(stringtoread, DIM_WORDS, stdin);
ret=sscanf(stringtoread, "%s %s", textname, word);
}while(ret!=2);
fp=fopen(textname, "r");
if(fp==NULL)
{
printf("Error: That file doesn't exist or could not be open\n");
exit(EXIT_FAILURE);
}
while(fgets(line, sizeof(line), fp))
{
verify = strstr(word, line);
if(verify!=NULL)
{
printf("The word was encountered in line %d\n", num);
printf("%s", line);
}
num++;
}
fclose(fp);
return EXIT_SUCCESS;
}
I tried my program with a file text.txt and trying to find the word file:
A text file (sometimes spelled "textfile": an old alternative name is "flatfile") is a kind of computer file that is structured as a sequence of lines of electronic text.
A text file exists within a computer file system.
The end of a text file is often denoted by placing one or more special characters, known as an end-of-file marker, after the last line in a text file.
Such markers were required under the CP/M and MS-DOS operating systems.
On modern operating systems such as Windows and Unix-like systems, text files do not contain any special EOF character.
"Text file" refers to a type of container, while plain text refers to a type of content. Text files can contain plain text, but they are not limited to such.
At a generic level of description, there are two kinds of computer files: text files and binary files.[1]
Problem is my program is not printing anything.
I think the problem might be here:
while(fgets(line, sizeof(line), fp))
{
verify = strstr(word, line);
if(verify!=NULL)
{
printf("The word was encountered in line %d\n", num);
printf("%s", line);
}
num++;
}
Since if I remove most of the code just to print all the lines of the file it prints them:
while(fgets(line, sizeof(line), fp)
printf("%s", line);
Can someone help me to fix this? Thanks!
You've got this backwards
verify = strstr(word, line);
you're searching for line in word when it should be
verify = strstr(line, word);
I have created a function that takes as a parameter the name of a source file, the name of a destination file and the beginning and end lines of the source file lines that will be copied to the destination file, like the example below. All I want to do is to input the lines that I want to copy to the other text file like the example below:
The code I show you just "reads" the content of the one text file and "writes" another one. I want to "write" specific lines that the user gives, not the whole text file
Inputs by the user:
Source_file.txt //the file that the destination file will read from
destination_file.txt //the new file that the program has written
2 3 // the lines that it will print to the destination file: 2-3
Source_file.txt:
1
2
3
4
5
6
destination_file.txt
2
3
code:
#include <stdio.h>
#include <stdlib.h>
void cp(char source_file[], char destination_file[], int lines_copy) {
char ch;
FILE *source, *destination;
source = fopen(source_file, "r");
if (source == NULL) {
printf("File name not found, make sure the source file exists and is ending at .txt\n");
exit(EXIT_FAILURE);
}
destination = fopen(destination_file, "w");
if (destination == NULL) {
fclose(source);
printf("Press any key to exit...\n");
exit(EXIT_FAILURE);
}
while ((ch = fgetc(source)) != EOF)
fputc(ch, destination);
printf("Copied lines %d from %s to %s \n",
lines_copy, source_file, destination_file, ".txt");
fclose(source);
fclose(destination);
}
int main() {
char s[20];
char d[20];
int lines;
printf("-Enter the name of the source file ending in .txt\n"
"-Enter the name of the destination file ending in .txt\n"
"-Enter the number of lines you want to copy\n\n");
printf(">subcopy.o ");
gets(s);
printf("destination file-> ");
gets(d);
printf("Lines: ");
scanf("%d", &lines);
cp(s, d, lines);
return 0;
}
In cp(), in order to select the lines to keep, you have to know their position in the input-file. Thus, you need to count lines.
Using fgets instead of fgetc will allow you to count the lines.
On the other hand, if I wanted to select lines 3 and 7 to 12 in a file, I'd use:
sed -n -e "3p;7,12p" < input.txt > output.txt
this is a very simple solution, let's say you know that the maximun length of a line will be 100 characters for simplicity (if a line is longer than 100 characters only the first 100 will be taken)
at the top (outside main) you can write
#ifndef MAX_LINE_SIZE
#define MAX_LINE_SIZE 100
#endif
i know many people don't like this but i think in this case it makes the code more elegant and easier to change if you need to modify the maximum line size.
to print only the wanted lines you can do something like this
char line[MAX_LINE_SIZE];
int count = 0;
while (fgets(line, MAX_LINE_SIZE, source)){
count++;
if (3 <= count && count <= 5){
fputs(line, destination);
}
}
The while loop will end when EOF is reched because fgets returns NULL.
P.S. there could be some slight errors here and there since i wrote it pretty fast and going by memory but in general it should work.
There are some problems in your program:
Do not use gets(), it may cause buffer overflows.
Always use type int to store the return value of fgetc() in order to distinguish EOF from regular byte values.
You pass an extra argument ".txt" to printf(). It will be ignored but should be removed nonetheless.
To copy a range of lines from source to destination, you can just modify your function this way:
#include <stdio.h>
#include <string.h>
#include <errno.h>
void cp(char source_file[], char destination_file[], int start_line, int end_line) {
int ch;
int line = 1, lines_copied;
FILE *source, *destination;
source = fopen(source_file, "r");
if (source == NULL) {
printf("Cannot open input file %s: %s\n",
source_file, strerror(errno));
exit(EXIT_FAILURE);
}
destination = fopen(destination_file, "w");
if (destination == NULL) {
printf("Cannot open output file %s: %s\n",
destination_file, strerror(errno));
fclose(source);
exit(EXIT_FAILURE);
}
while ((ch = fgetc(source)) != EOF) {
if (line >= start_line && line <= end_line) {
fputc(ch, destination);
}
if (ch == '\n') {
line++;
}
}
lines_copied = 0;
if (line > start_line) {
if (line >= end_line) {
lines_copied = end_line - start_line + 1;
} else {
lines_copied = line - start_line + 1;
}
}
printf("Copied lines %d from %s to %s\n",
lines_copy, source_file, destination_file);
fclose(source);
fclose(destination);
}
int main() {
char source_file[80];
char destination_file[80];
int start_line, end_line;
printf("-Enter the name of the source file ending in .txt\n"
"-Enter the name of the destination file ending in .txt\n"
"-Enter the start and end line\n\n");
printf(">subcopy.o ");
if (scanf("%79s", source_file) != 1) {
return 1;
}
printf("destination file-> ");
if (scanf("%79s", destination_file) != 1) {
return 1;
}
printf("Start and end lines: ");
if (scanf("%d %d", &start_line, &end_line) != 2) {
return 1;
}
cp(source_file, destination_file, start_line, end_line);
return 0;
}