Parsing every word - c

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;
}

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: >
///////////

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%10 - 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;
}

Related

Split file as argument by '/' (slash)

I have a bit of code and I need to split the words in the filename and store them separately.
Example:
Input -> filename ( e.g. /Users/user/Documents/uni)
Storage in variable/array as separate words ( not sure how):
char array/struct array = Users user Documents uni
How can I achieve the above example of storing words with C?
Here is my code:
int main(int argc, char *argv[])
{
char filename[255];
for (int i = 0; i < argc; i++)
{
strcpy(&filename[i], argv[i]);
}
}
Thanks in advance
Would you please try the following:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
char filename[BUFSIZ]; // pathname
int i;
int n = 0; // number of words
char **ary = NULL; // array of strings
char *tok; // pointer to each token
if (argc != 2) { // verify aruguments
fprintf(stderr, "usage: %s pathname\n", argv[0]);
exit(1);
}
strncpy(filename, argv[1], BUFSIZ);
for (tok = strtok(filename, "/"); tok != NULL; tok = strtok(NULL, "/")) {
if (NULL == (ary = realloc(ary, (n + 1) * sizeof(*ary)))) {
// enlarge array of strings
perror("realloc");
exit(1);
}
if (NULL == (ary[n] = malloc(strlen(tok) + 1))) {
// allocate memory for the word
perror("malloc");
exit(1);
}
strncpy(ary[n], tok, strlen(tok) + 1);
// copy the token to the array
n++;
}
// see the results
for (i = 0; i < n; i++) {
printf("[%d] %s\n", i, ary[i]);
}
// free the allocated memory
for (i = 0; i < n; i++) {
free(ary[i]);
}
free(ary);
return 0;
}
If you compile the code to the executable a.out, the outout will look like:
$ ./a.out /Users/user/Documents/uni
[0] Users
[1] user
[2] Documents
[3] uni
I have managed to achieve the desired outcome with this piece of code:
int main(int argc, char *argv[])
{
char word[255];
const char s[2] = "/";
char *token;
if( argc == 2 ) {
printf("The argument supplied is %s\n", argv[1]);
}
else if( argc > 2 ) {
printf("Too many arguments supplied.\n");
}
strcpy(word, argv[0]);
token = strtok(word, s);
while( token != NULL ) {
printf( " %s\n", token );
token = strtok(NULL, s);
}
}

Replace a word in C

can you advice me? I have a string from a file. When i see the string on my console, i need to write the word on which i want to change, and output the result in another file. For example: "Hello my girl" the word i want change "girl" on another word "boy". I can use the library
Can you advice me the algorithm which helps me to change the word?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char my_string[256];
char* ptr;
FILE *f;
if ((f = fopen("test.txt", "r"))==NULL) {
printf("Cannot open test file.\n");
exit(1);}
FILE *out;
if((out=fopen("result.txt","w"))==NULL){
printf("ERROR\n");
exit(1);
}
fgets (my_string,256,f);
printf ("result: %s\n",my_string);
ptr = strtok (my_string," ");
while (ptr != NULL)
{
printf ("%s \n",ptr);
ptr = strtok (NULL," ");
}
char old_word [10];
char new_word [10];
char* ptr_old;
char* ptr_new;
printf ("Enter your old word:\n");
ptr_old= gets (old_word);
printf ("Your old word:%s\n",old_word);
printf ("Enter new old word:\n");
ptr_new = gets (new_word);
printf ("Your new word:%s\n",new_word);
fclose(f);
fclose(out);
return 0;
}
i tried to split inputting string into words. Now its dead end.
This code will help you. you have to pass 4 args at runtime.
./a.out "oldword" "newword" "file name from take the old word" "file name where to copy"
$ ./a.out girl boy test.txt result.txt
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int args, char *argv[4])
{
FILE *f1;
FILE *f2;
char *strings=0;
char *newstrings=0;
char *token=NULL;
strings=(char *)malloc(1000);
newstrings=(char *)malloc(1000);
if((strings==NULL)||(newstrings==NULL))
{
printf("Memory allocation was not successfull.");
return 0;
}
if(args<4)
{
puts("Error: Not enough input parameters");
puts("Usage: ./change <oldword> <newword> <infile> <newfile>");
return 0;
}
f1=fopen(argv[3],"r");
f2=fopen(argv[4],"w");
if(f1==NULL)
{
puts("No such file exists");
return 0;
}
while(fgets(strings,1000,f1)!=NULL)
{
if(strstr(strings,argv[1])!=NULL)
{
token=strtok(strings,"\n\t ");
while(token!=NULL)
{
if(strcmp(token,argv[1])==0)
{
strcat(newstrings,argv[2]);
strcat(newstrings," ");
}
else
{
strcat(newstrings,token);
strcat(newstrings," ");
}
token=strtok(NULL,"\n\t ");
}
}
else
{
strcpy(newstrings,strings);
}
fputs(newstrings,f2);
}
free(strings);
free(newstrings);
printf("New file <%s> generated!\n",argv[4]);
fclose(f1);
fclose(f2);
return 0;
}
You can use a function like the shown function in the demonstrative program below
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char * replace(const char *s, const char *src, const char *dsn)
{
size_t n = 0;
size_t src_len = strlen(src);
size_t dsn_len = strlen(dsn);
for (const char *p = s; (p = strstr(p, src)) != NULL; p += src_len)
{
n++;
}
char *result = malloc(strlen(s) + n * (src_len - dsn_len) + 1);
const char *p = s;
char *t = result;
if (n != 0)
{
for (const char *q; (q = strstr(p, src)) != NULL; p = q + src_len)
{
memcpy(t, p, q - p);
t += q - p;
memcpy(t, dsn, dsn_len);
t += dsn_len;
}
}
strcpy(t, p);
return result;
}
int main( void )
{
char s[] = " the girl and boy are relatives";
char *p = replace(s, "girl", "boy");
puts(s);
puts(p);
free(p);
}
The program output is
the girl and boy are relatives
the boy and boy are relatives
#include <stdio.h>
#include <string.h>
int main ()
{
char file_path[40] = { 0 }, stf[255] = { 0 }, rtf[255] = { 0 }, str[255] = { 0 };
FILE* file = NULL;
FILE *e_f;
if((e_f=fopen("result.txt","w"))==NULL){
printf("ERROR\n");
exit(1);
}
do
{
printf("Enter file path: ");
fgets(file_path, 40, stdin);
file_path[strlen(file_path) - 1] = '\0';
file = fopen(file_path, "r+");
}
while(file == NULL);
printf("Enter text to find: ");
fgets(stf, 255, stdin);
stf[strlen(stf) - 1] = '\0';
printf("Enter text to replace: ");
fgets(rtf, 255, stdin);
rtf[strlen(rtf) - 1] = '\0';
while(fgets(str, 255, file) != NULL)
{
char* tmp_ptr = strstr(str, stf);
while(tmp_ptr != NULL)
{
char tmp_str[255];
strcpy(tmp_str, tmp_ptr + strlen(stf));
strcpy(str + strlen(str) - strlen(tmp_ptr), rtf);
strcat(str, tmp_str);
tmp_ptr = strstr(str, stf);
}
printf("%s", str);
}
fclose(file);
fclose(e_f);
return 0;
}
That was i need. Thanks everybody for helping!
I did a function:
#include <stdio.h>
#include <string.h>
#define MAX 50
void Change (char x[], char cx, char nu){
int i;
for(i=0;i<strlen(x);i++) {
if (x[i]==cx){
x[i] = nu;
}
}
}
int main () {
char str[MAX];
char ch;
char new;
printf("Insert the string\n");
scanf("%s",str);
printf("Insert the word that you want to change\n");
scanf(" %c",&ch);
printf("the new word\n");
scanf(" %c",&new);
Change(str, ch, new);
printf("The new word is %s\n",str );
return 0;
}

Character array elements get replaced when using printf

I am taking the lines from a text file and storing the lines in an array. Then I am splitting the lines into separate words and storing them in another array. But I have a problem with the words stored.
Text file content:
ls -l hahaha
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *trim (char *s) {
int i = strlen(s)-1;
if ((i > 0) && (s[i] == '\n'))
s[i] = '\0';
return s;
}
int main(int argc, char *argv[]){
FILE *fp;
char *output = NULL;
fp= fopen("ints.txt", "r");
//fscanf and fprintf is used for files and is same is printf and scanf
fprintf(fp, "Testing...\n");
//fgetsc for single character in file and fputc to write
//
size_t len = 0;
ssize_t read;
const char s[2]=" ";
char *token;
char line[256];
char *lines[10];
char *eof;
char *args[10];
//=====nulling the array lines====
for(int p=0; p<10; p++)
{
lines[p]=NULL;
}
int i=0;
if (fp == NULL)
{
exit(EXIT_FAILURE);
}
else
{
while(fgets(line, 256, fp)!= NULL)
{
lines[i] = strdup(line);
//printf("%s", lines[i]);
i++;
}
}
fclose(fp);
int k=0;
for(int j=0; j<9; j++)
{
if(lines[j]!=NULL)
{
token =strtok(lines[j], s); //s is the delimiter
while(token != NULL)
{
trim(token);
//printf("%s\n", token);
args[k] = token;
token = strtok(NULL,s);
k++;
}
}
}
printf("%s\n",args[0]);
printf("%s\n", args[1]);
printf("%s\n", args[2]);
printf("%s something\n", args[0]);
printf("%s something\n" , args[2]);
printf("program done\n");
}
Output:
ls
-l
hahaha
ls something
something //the hahaha part disappears for the last printf**
program done

while loop terminating before it is supposed to C

This program is supposed to copy an existing txt file to a new txt code file. However is isn't working right. For some reason it always stops after the third iteration.
Suggestions?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char fileNameIn[100];
char fileNameOut[100];
FILE *ptrIn = NULL; //____ File Pointers
FILE *ptrOut = NULL;
char str[1000]; //this is used at fgets and it obtains sentences
/*_________________Counter variables)*/
char *token;
int ctr = 0;
int ndel = -1;
char wordA[10];
char sentence[101];
char del[10] = " !-,.";
;
int temp = 0;
printf("Enter the input filename: \n");
// gets(fileNameIn);
scanf("%s", fileNameIn);
//printf("You entered: %s\n",fileNameIn);
printf("Enter the output filename: \n");
scanf("%s", fileNameOut);
ptrIn = fopen(fileNameIn, "r"); // r is to read
ptrOut = fopen(fileNameOut, "w"); //w is to write on file
if (ptrIn == NULL || ptrOut == NULL) {
printf("Unable to open file\n");
exit(1);
}
//while(fgets (str,sizeof(str), ptrIn) )
while (fgets(str, sizeof(str), ptrIn)) { // while we are not at the end of the file
puts(str);
// if(temp==0)
// {
token = strtok(str, del);
temp = -1;
printf(
"Enter position of word to delete (Start counting at 0). Enter -1 to skip deletion:\n");
scanf("%d", &ndel);
printf("You selected: %d\n", ndel);
while (token != NULL) // while loop inside a sentence
{
if (ctr != ndel) {
strcpy(wordA, token);
}
token = strtok(NULL, del);
if (ctr != ndel) {
strcat(sentence, wordA);
strcat(sentence, " ");
printf("halfway?");
}
ctr++;
} // endof sentence loop
fprintf(ptrOut, "%s", sentence);
printf("the sentence is now:\n%s", sentence);
printf("___________________________________________");
printf("\n");
strcpy(sentence, "");
ctr = 0;
ndel = -1;
} //end of while loop eof
printf("Finish the main: ");
fflush(ptrOut);
fclose(ptrIn);
fclose(ptrOut);
return EXIT_SUCCESS;
}
This is an example of the existing file:
test.txt:
hello my name is john.
this is a test.
after the third line the while
loop stops
this does the get copied
You strcat() to senetence wihtout initializing it, strcat() will search for the terminating nul byte of it's first argument and start copying characters from it's second argument start from that position, so a simple
sentence[0] = '\0';
right after the outer while loop will fix it, but your code needs reformatting and you should make it safer by checking every single potential undefined behavior cause.
This is the code and it now works correctly
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char fileNameIn[100] = {0};
char fileNameOut[100] = {0};
FILE *ptrIn = NULL;
FILE *ptrOut = NULL;
char str[1024] = {0};
char *token = NULL;
int ctr = 0;
int ndel = -1;
char wordA[1024] = {0};
char sentence[1024] = {0};
char del[] = " !-,.";
int temp = 0;
printf("Enter the input filename > ");
fflush(stdout);
scanf("%99s", fileNameIn);
printf("Enter the output filename > ");
fflush(stdout);
scanf("%99s", fileNameOut);
ptrIn = fopen(fileNameIn, "r"); // r is to read
if (ptrIn == NULL)
{
printf("Unable to open file %s\n", fileNameIn);
return -1;
}
ptrOut = fopen(fileNameOut, "w"); // w is to write on file
if (ptrOut == NULL)
{
fclose(ptrIn);
printf("Unable to open file %s\n", fileNameOut);
return -1;
}
while (fgets(str, sizeof(str), ptrIn)) // while we are not at the end of the file
{
puts(str);
token = strtok(str, del);
temp = -1;
printf("Enter position of word to delete (Start counting at 0) `-1 to skip deletion' > ");
if (scanf("%d", &ndel) != 1)
continue;
printf("You selected: %d\n", ndel);
sentence[0] = '\0';
while (token != NULL)
{
if (ctr != ndel)
strcpy(wordA, token);
token = strtok(NULL, del);
if (ctr != ndel)
{
strcat(sentence, wordA);
strcat(sentence, " ");
}
ctr++;
}
fprintf(ptrOut, "%s", sentence);
printf("the sentence is now:\n%s", sentence);
printf("\n");
ctr = 0;
ndel = -1;
}
printf("Finish the main: ");
fflush(ptrOut);
fclose(ptrIn);
fclose(ptrOut);
return EXIT_SUCCESS;
}

why is this array not outputting properly now even though it worked perfectly during an earlier test

I am working on a program that includes a selection of code which is "supposed" to filter a string in order to prevent non-alphanumeric characters (except for underscores) from being passed further on into the program. The part that does this worked fine when I tested it before implementing it in the main program (as shown below), but when I run it now the output is just repeated a bunch of times until there is a segmentation fault, and i cannot for the life of me figure out what is causing this to happen, so if anyone could help with this problem I would very much appreciate it, thanks! also for ease of seeing where this is implemented in the main program, i have taken a screenshot of where it is located in the main code http://i.imgur.com/dKLgx.png, and my apologies for the long post length
austin#Ruby:~/cprac$ ./words
[hel123_lo]
testing code that worked
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void) {
int i;
char *p;
char stg[] = "hel123*^_l!o";
char output[200] = {0x00};
int index = 0;
p = stg;
while( *p )
{
if (isalnum(*p) || *p == '_')
{
output[index++] = *p;
}
p++;
}
printf("[%s]\n", output);
return 0;
}
main code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#ifndef max
#define max(a, b) ((a)>(b))? (a) : (b)
#endif
long GetFileSize(FILE *fp){
long fsize = 0;
fseek(fp,0,SEEK_END);
fsize = ftell(fp);
fseek(fp,0,SEEK_SET);//reset stream position!!
return fsize;
}
char *lastline(char *filepath){
FILE *fp;
char buff[4096+1];
int size,i;
long fsize;
if(NULL==(fp=fopen(filepath, "r"))){
perror("file cannot open at lastline");
return NULL;
}
fsize= -1L*GetFileSize(fp);
if(size=fseek(fp, max(fsize, -4096L), SEEK_END)){
perror("cannot seek");
exit(0);
}
size=fread(buff, sizeof(char), 4096, fp);
fclose(fp);
buff[size] = '\0';
i=size-1;
if(buff[i]=='\n'){
buff[i] = '\0';
}
while(i >=0 && buff[i] != '\n')
--i;
++i;
return strdup(&buff[i]);
}
int main(int argc, char *argv[], char *envp[]){
char *last;
char *name;
char field_x[128];
char field_y[128];
char field_z[128];
char field_world[128];
char field_cause[128];
char field_killer[128];
name = getenv("MCEXEC_PLAYERNAME");
char *filename;
char *p;
char *ispvp;
// m
int i;
char *f;
char output[200] = {0x00};
int index = 0;
filename = malloc(sizeof "/home/minecraft/freedonia/playerdata/deathlog-.txt" - 1 + strlen(name) + 1);
if (!filename) exit(EXIT_FAILURE);
snprintf(filename,4096,"/home/minecraft/freedonia/playerdata/deathlog- %s.txt",name);
last = lastline(filename);
if( last != NULL ) {
printf( "%s\n", last );
sscanf(last, "%*[^:]:%*[^:]:%*[^:]:%127[^:]:", field_x);
sscanf(last, "%*[^:]:%*[^:]:%*[^:]:%*[^:]:%127[^:]:", field_y);
sscanf(last, "%*[^:]:%*[^:]:%*[^:]:%*[^:]:%*[^:]:%127[^:]:", field_z);
sscanf(last, "%*[^:]:%*[^:]:%*[^:]:%*[^:]:%*[^:]:%*[^:]:%127[^:]:", field_world);
sscanf(last, "%*[^:]:%*[^:]:%*[^:]:%*[^:]:%*[^:]:%*[^:]:%*[^:]:%127[^:]:", field_cause);
p = strchr(field_cause, '_');
printf( "X coord: %s\n", field_x);
printf( "Y coord: %s\n", field_y);
printf( "Z coord: %s\n", field_z);
printf( "World: %s\n", field_world);
printf( "Cause: %s\n", field_cause);
while (p != NULL) {
ispvp = "true";
// printf ("found at %d\n",p - field_cause + 1);
sscanf(field_cause, "%*[^_]_%128[^_]_", field_killer);
printf( "%s\n", field_killer);
f = field_cause;
while( *f )
{
if (isalnum(*f) || *f == '_')
{
output[index++] = *f;
}
f++;
}
printf("[%s]\n", output);
// p = strchr(p + 1, '_');
}
}
// printf("\"%s\"\n", last);
free(last);
return 0;
}
while (p != NULL) {
ispvp = "true";
// printf ("found at %d\n",p - field_cause + 1);
sscanf(field_cause, "%*[^_]_%128[^_]_", field_killer);
printf( "%s\n", field_killer);
f = field_cause;
while( *f )
{
if (isalnum(*f) || *f == '_')
{
output[index++] = *f;
}
f++;
}
printf("[%s]\n", output);
// p = strchr(p + 1, '_');
}
P never changes in this block, so it will always be != NULL.

Resources