My program reads a txt file and can print all the contents one by one to the console but I have to store every variable in a different string and then print them out seperatly to the console.
Expected output is :
///////////
First word: Grep
Second word: danger
Third word: <
////////////
First word: ls
Second word: -a
Third word : -
/////////
Output of the program:
grep
danger
<
ls
-a
-
Input file content:
grep danger <
ls -a wc hw2 . c >
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, char* argv[])
{
FILE * file;
file = fopen("commands.txt","r");
char *token;
const char s[2] = " ";
fseek(file,0,SEEK_END);
int length = ftell(file);
fseek(file,0,SEEK_SET);
char*string = malloc(sizeof(char) * (length 1));
char c;
int i = 0 ;
while( (c= fgetc(file)) != EOF) {
string[i]=c;
i ;
}
string[i]='\0';
token = strtok(string, s);
while( token != NULL ) {
printf( " %s\n", token );
token = strtok(NULL, s);
}
return 0;
}
CodePudding user response:
I suggest that you create a loop which reads and processes one line at a time. In order to read a single line at once, you can use the function fgets
. This is easier than reading a single character at a time using fgetc
.
You can define an array which maps the numbers 1
to 10
to the individual string literals "First"
, "Second"
, "Third"
, etc:
const char *map[] = {
"Zeroth",
"First", "Second", "Third", "Fourth", "Fifth",
"Sixth", "Seventh", "Eighth", "Ninth", "Tenth"
};
Now you can then change the lines
while( token != NULL ) {
printf( " %s\n", token );
token = strtok(NULL, s);
}
to:
for ( int i = 1; i < 11 && token != NULL; i ) {
printf( "%s word: %s\n", map[i], token );
token = strtok(NULL, s);
}
That way, it will print:
First word: Grep
Second word: danger
Third word: <
After making these changes, your program should look like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUM_MAPPINGS 11
int main( void )
{
FILE *file;
char line[200];
char *token;
const char *delimiter = " ";
const char *separator = "///////////";
const char *map[NUM_MAPPINGS] = {
"Zeroth",
"First", "Second", "Third", "Fourth", "Fifth",
"Sixth", "Seventh", "Eighth", "Ninth", "Tenth"
};
//attempt to open file
file = fopen( "commands.txt", "r" );
if ( file == NULL )
{
fprintf( stderr, "Error opening file!\n" );
exit( EXIT_FAILURE );
}
//print separator
printf( "%s\n", separator );
//process one line per loop iteration
while ( fgets( line, sizeof line, file ) != NULL )
{
//remove newline character from input, if it exists
line[strcspn(line,"\n")] = '\0';
//find first token
token = strtok( line, delimiter );
for ( int i = 1; i < NUM_MAPPINGS && token != NULL; i )
{
//print current token
printf( "%s word: %s\n", map[i], token );
//find next token
token = strtok( NULL, delimiter );
}
//print separator
printf( "%s\n", separator );
}
//cleanup
fclose( file );
return 0;
}
For the input specified in the question, this program has the following outptu:
///////////
First word: grep
Second word: danger
Third word: <
///////////
First word: ls
Second word: -a
Third word: wc
Fourth word: hw2
Fifth word: .
Sixth word: c
Seventh word: >
///////////
CodePudding user response:
Good answer...
I expanded it a bit :)
#include <stdio.h>
#include <stdint.h>
void my_print(int num, char *s)
{
char level_0[19][12] =
{
"First",
"Second",
"Third",
"Forth",
"Fifth",
"Sixth",
"Seventh",
"Eighth",
"Nineth",
"Tenth",
"Eleventh",
"Twelveth",
"Thirteenth",
"Forteenth",
"Fifteenth",
"Sixteenth",
"Seventeenth",
"Eighteenth",
"Nineteeth"
};
char level_1[8][7] =
{
"Twent",
"Thirt",
"Fort",
"Fift",
"Sixt",
"Sevent",
"Eight",
"Ninet"
};
if (num < 20)
{
printf("%s word: %s\n", level_0[num - 1], s);
}
else if (num % 10 == 0)
{
printf("%sieth word: %s\n", level_1[num/10 - 2]);
}
else
{
printf("%sy-%s word: %s\n", level_1[num/10 - 2], level_0[num - 1], s);
}
}
int get_token(FILE *fp, char *s, int max_length)
{
char c;
int counter = 0;
s[0] = '\0';
while (!feof(fp))
{
if (counter == max_length) { return -2; }
c = getc(fp);
if (c == ' ') { return 1; }
if (c == '\n') { return 2; }
*s = c;
s ;
*s = '\0';
counter ;
}
return -1;
}
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Arguments Error.\nUsage: parse_words [filename].\n");
return 1;
}
const char *fname = argv[1];
FILE *fp;
char token[80];
size_t len = 80;
int word_count = 0;
int get_token_state;
fp = fopen(fname, "r");
if (fp == NULL)
{
printf("Error opening file %s!\n", fname);
return 1;
}
printf("///////////\n");
while ((get_token_state = get_token(fp, token, len)) != -1)
{
if (get_token_state == -2)
{
printf("Warning, overflow near %s\n.", token);
}
else if (get_token_state == 1)
{
word_count ;
my_print(word_count, token);
}
else if (get_token_state == 2)
{
word_count ;
my_print(word_count, token);
word_count = 0;
printf("///////////\n");
}
}
fclose(fp);
return 0;
}