Code doesn't read what it should read - c

Ok, so I have to write a C program that allocated memory dynamically, that reads n lines of char text and that counts number of appearances of a specific word. Unfortunately, after I read n, then the n lines, then the m and k, it won't read cuv1 and it will always show 0. Any idea why?
This is the code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char c[100][100];
int n;
int prima(const char *s1, char *cuv1)
{
int ok=0, i;
char *p;
p=strstr(s1, cuv1);
while(p)
{
ok++;
strcpy(p, p+strlen(cuv1));
p=strstr(p, cuv1);
}
return ok;
}
int main()
{
int m, k, i, l, nr=0;
char t[20], s1[12000];
scanf("%d", &n);
char *text, *v[n], cuv1[12000];
getchar();
for(i=0;i<n;i++)
{
text=malloc(12000*sizeof(char));
fgets(text, 12000, stdin);
l=strlen(text);
text[l-1]='\0';
l=l-1;
v[i]=malloc(l*sizeof(char));
strcpy(v[i], text);
}
scanf("%d", &m);
for(i=1;i<=m;i++)
{
scanf("%d", &k);
if(k==1)
{
fgets(cuv1, 12000, stdin);
for(i=1;i<=n;i++)
{
strcpy(s1, v[i]);
nr=nr+prima(s1);
}
printf("%d", nr);
}
}
return 0;
}

Unfortunately I get this error: incompatible pointer to integer conversion passing 'char [12000]' to parameter of type 'char'
Check the prototype of strstr - then you'll see your p=strstr(s1, cuv1); is wrong as cuv1 is a char, not a const string for the second parameter of strstr (const char *).
char * strstr ( const char *, const char * );
So for a start, change your int prima(char s1) to int prima(const char *s1), or int prima(const char s1[]).

after applying the comments and fixing some logic problems
the following code makes significant use of malloc() and free()
You will need to add any multiple search string capabilities
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int prima( char *strToSearch, char *strToFind)
{
int countFound=0;
char *p = strToSearch;
do
{
if( NULL != (p = strstr( p, strToFind) ) )
{ // then sub string found
countFound++;
p += strlen(strToFind);
}
} while(p);
return countFound;
} // end function: prima
void flushstdin( void )
{
int ch;
while( (ch = getchar()) != EOF && '\n' != ch) ;
}
void cleanup( char **linesToFree, int lineCount )
{
for( int i=0; i < lineCount; i++ )
{
free( linesToFree[i] );
}
}
int main( void )
{
int countLinesToRead = 0;
printf( "Enter number of lines to read: " );
if( 1 != scanf("%d", &countLinesToRead) )
{ // then scanf failed
perror( "scanf for count of lines to read failed" );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
char **ptrToLines = NULL;
if( NULL == (ptrToLines = malloc( countLinesToRead*sizeof(char*) ) ) )
{ // then malloc failed
perror( "malloc for array of char pointers failed" );
exit( EXIT_FAILURE );
}
// implied else, malloc successful
// init to all NULLs so easy to recover if error occurs
for( int i = 0; i < countLinesToRead; i++ )
{
ptrToLines[i] = NULL;
}
flushstdin();
for( int i = 0; i < countLinesToRead; i++ )
{
size_t lineLen = 1;
if( 0 < getline( &ptrToLines[i], &lineLen, stdin) )
{ // then read of line successful
// remove any trailing newline char
char *newline = NULL;
if( NULL != (newline = strstr( ptrToLines[i], "\n") ) )
{ // then newline to be trimmed
*newline = '\0';
}
}
else
{ // getline failed
perror( "getline for line to search failed" );
cleanup( ptrToLines, countLinesToRead );
exit( EXIT_FAILURE );
}
}
char *strToFind = NULL;
size_t searchLen = 1;
printf( "Enter sub string to search for: " );
if( 0 < getline( &strToFind, &searchLen, stdin) )
{ // then read of line successful
// remove any trailing newline char
char *newline = NULL;
if( NULL != (newline = strstr( strToFind, "\n") ) )
{ // then newline to be trimmed
*newline = '\0';
}
}
else
{ // getline failed
perror( "getline for string to find failed" );
cleanup( ptrToLines, countLinesToRead );
exit( EXIT_FAILURE );
}
int countFound = 0;
for(int i=0; i<countLinesToRead; i++)
{
countFound += prima( ptrToLines[i], strToFind);
}
printf("%d\n", countFound);
cleanup( ptrToLines, countLinesToRead );
return 0;
}
here is the results of a run of the above code:
Enter number of lines to read: 2
adfadfadfadf adf adb
abcdef adfadf
Enter sub string to search for: adf
7

Related

C language reading from file and placing in variables

In a text file I have the form Type:Username Password, how do I place it in three different variables, so that the variable Type is in the variable type, username is in username, and password is in password in C ?
Example:
Admin:Username Password
How to make?
Type:Admin
User:Username
Pw:Password
Here's my code:
int ch;
int i = 0;
while ((ch = fgetc(fp)) != EOF) {
// Check for the colon character
if (ch == ':') {
// We have reached the end of the type string
// Move to the next variable
i = 0;
continue;
}
// Check for the space character
if (ch == ' ')
{
// We have reached the end of the username string
// Move to the next variable
i = 0;
continue;
}
// Store the character in the appropriate variable
if (i < 50) {
if (type[0] == 0) {
type[i] = ch;
} else if (username[0] == 0) {
username[i] = ch;
} else {
password[i] = ch;
}
i++;
}
}
Considering your initial requirement that you posted in your Question, that a text file consists of following line:
Admin:Username Password
To store Admin in variable type, Username in variable username and similarly Password in variable Password.
You can declare a structure something similar to:
typedef struct user {
char type[512];
char username[512];
char password[512];
} user;
And as #IngoLeonhardt commented, that strtok() or strchr() can be used to parse the line read from the text file, you can refer the below simple example code snippet to understand and further improve the logic.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct user {
char type[512];
char username[512];
char password[512];
} user;
int main(void)
{
FILE *file = fopen("test.txt","r");
char *line = NULL;
size_t linesize = 0;
char *token;
const char colon[2] = ":";
const char space[2] = " ";
user user_1;
if (file)
{
while (getline(&line, &linesize, file) != -1)
{
printf("%s\n", line);
token = strtok(line, colon);
strcpy(user_1.type, token);
token = strtok(NULL, space);
strcpy(user_1.username, token);
token = strtok(NULL, space);
strcpy(user_1.password, token);
printf("%s\n", user_1.type);
printf("%s\n", user_1.username);
printf("%s", user_1.password);
free(line);
}
fclose(file);
}
return 0;
}
PS: There may be some flaws/bugs in above implementation, please consider the above code just as an example.
Here is a solution which reads one character at a time from the file:
#include <stdio.h>
#include <stdlib.h>
#define MAX_STRING_SIZE 200
int main( void )
{
char type[MAX_STRING_SIZE];
char user[MAX_STRING_SIZE];
char pw[MAX_STRING_SIZE];
FILE *fp;
int ch;
int i;
//open the input file
fp = fopen( "input.txt", "r" );
if ( fp == NULL )
{
fprintf( stderr, "Error opening file!\n" );
exit( EXIT_FAILURE );
}
//read first token
i = 0;
while ( ( ch = fgetc( fp ) ) != ':' )
{
if ( ch == EOF )
{
fprintf( stderr, "Input error!\n" );
exit( EXIT_FAILURE );
}
if ( i == MAX_STRING_SIZE )
{
fprintf( stderr, "Sub-string is too long!\n" );
exit( EXIT_FAILURE );
}
type[i++] = ch;
}
type[i] = '\0';
//read second token
i = 0;
while ( ( ch = fgetc( fp ) ) != ' ' )
{
if ( ch == EOF )
{
fprintf( stderr, "Input error!\n" );
exit( EXIT_FAILURE );
}
if ( i == MAX_STRING_SIZE )
{
fprintf( stderr, "Sub-string is too long!\n" );
exit( EXIT_FAILURE );
}
user[i++] = ch;
}
user[i] = '\0';
//read third token
i = 0;
while ( ( ch = fgetc( fp ) ) != EOF )
{
if ( i == MAX_STRING_SIZE )
{
fprintf( stderr, "Sub-string is too long!\n" );
exit( EXIT_FAILURE );
}
pw[i++] = ch;
}
pw[i] = '\0';
//close the file
fclose( fp );
//print the three strings
printf( "Type:%s\n", type );
printf( "User:%s\n", user );
printf( "Pw:%s\n", pw );
}
For the input stated in the question, this program has the desired output:
Type:Admin
User:Username
Pw:Password
Here is an alternative solution, which reads a whole line at once:
This solution reads a line from the file as a string, by using the function fgets. After doing that, it uses the function strchr to find the ':' and ' ' delimiter characters in the string. Once they are found, the characters between the tokens can be copied so that they form a string.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define MAX_STRING_SIZE 200
bool read_exactly_one_line( char buffer[], int buffer_size, FILE *fp );
int main( void )
{
char type[MAX_STRING_SIZE];
char user[MAX_STRING_SIZE];
char pw[MAX_STRING_SIZE];
FILE *fp;
char line[500];
char *p, *q;
int token_length;
//open the input file
fp = fopen( "input.txt", "r" );
if ( fp == NULL )
{
fprintf( stderr, "Error opening file!\n" );
exit( EXIT_FAILURE );
}
//read one line of input
if ( ! read_exactly_one_line( line, sizeof line, fp ) )
{
fprintf( stderr, "File is empty!\n" );
exit( EXIT_FAILURE );
}
//find the delimiter between the first and second token
p = strchr( line, ':' );
if ( p == NULL )
{
fprintf( stderr, "Unable to find first delimiter!\n" );
exit( EXIT_FAILURE );
}
//verify that first token is not too large
token_length = p - line;
if ( token_length >= MAX_STRING_SIZE )
{
fprintf( stderr, "Token too large!\n" );
exit( EXIT_FAILURE );
}
//copy the first token
memcpy( type, line, token_length );
type[token_length] = '\0';
//move pointer to start of second token
p++;
//find the delimiter between the second and third token
q = strchr( p, ' ' );
if ( q == NULL )
{
fprintf( stderr, "Unable to find second delimiter!\n" );
exit( EXIT_FAILURE );
}
//verify that second token is not too large
token_length = q - p;
if ( token_length >= MAX_STRING_SIZE )
{
fprintf( stderr, "Token too large!\n" );
exit( EXIT_FAILURE );
}
//copy the second token
memcpy( user, p, token_length );
user[token_length] = '\0';
//move pointer to start of third token
q++;
//verify that third token is not too large
token_length = strlen( q );
if ( token_length >= MAX_STRING_SIZE )
{
fprintf( stderr, "Token too large!\n" );
exit( EXIT_FAILURE );
}
//copy the third token
memcpy( pw, q, token_length );
pw[token_length] = '\0';
//close the file
fclose( fp );
//print the three strings
printf( "Type:%s\n", type );
printf( "User:%s\n", user );
printf( "Pw:%s\n", pw );
}
//This function will read exactly one line and remove the newline
//character, if it exists. On success, it will return true. If this
//function is unable to read any further lines due to end-of-file,
//it returns false. If it fails for any other reason, it will not
//return, but will print an error message and call "exit" instead.
bool read_exactly_one_line( char buffer[], int buffer_size, FILE *fp )
{
char *p;
//attempt to read one line from the stream
if ( fgets( buffer, buffer_size, fp ) == NULL )
{
if ( ferror( fp ) )
{
fprintf( stderr, "Input error!\n" );
exit( EXIT_FAILURE );
}
return false;
}
//make sure that line was not too long for input buffer
p = strchr( buffer, '\n' );
if ( p == NULL )
{
//a missing newline character is ok if the next
//character is a newline character or if we have
//reached end-of-file (for example if the input is
//being piped from a file or if the user enters
//end-of-file in the terminal itself)
if ( getc(fp) != '\n' && !feof(stdin) )
{
printf( "Line input was too long!\n" );
exit( EXIT_FAILURE );
}
}
else
{
//remove newline character by overwriting it with a null
//character
*p = '\0';
}
return true;
}
This program has the same output as the first one.

How can I navigate through an array of strings of any length in C?

Understanding handling direct pointers in C
Here is a code that works for an array of strings for fixed number of items and fixed line length :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXNAMELEN 100
#define MAXLINELEN 100
#define MAXITEMS 1000
int main(int argc, char ** argv) {
FILE * infile, * outfile;
char name[MAXNAMELEN];
char line[MAXLINELEN];
char lines[MAXITEMS][MAXLINELEN];
int i, items = 0;
printf("Enter a source filename: ");
fgets(name, sizeof(name), stdin);
name[strlen(name)-1] = '\0'; // strip newline
infile = fopen(name, "r");
while (fgets(line, sizeof(line), infile)) {
strcpy(lines[items], line);
items++;
}
qsort(lines, items, MAXLINELEN, strcmp);
printf("Enter a destination filename: ");
fgets(name, sizeof(name), stdin);
name[strlen(name)-1] = '\0'; // strip newline
outfile = fopen(name, "w");
for (i=0; i<items; i++) {
fputs(lines[i], outfile);
}
fclose(infile);
fclose(outfile);
}
Problem description and code
If I try to read an input.txt file that is within MAXLINELEN and MAXITEMS, the program works fine. Now imagine I am reading from a much larger "inputfile" line by line where maximum line length could be anything, then I would have to use a character pointer (char*) to read the input. char* linesptr[MAXITEMS];
Here is my code where I am trying to accomplish reading from an input file line by line delimited by a newline character.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#define MAXNAMELEN 1000
#define MAXLINELEN 1000
#define MAXITEMS 100000
char* linesptr[MAXITEMS];
int
main(int argc, char ** argv) {
FILE * infile, * outfile;
char name[MAXNAMELEN];
char line[MAXLINELEN];
int i, items = 0;
printf("Enter a source filename: ");
fgets(name, MAXNAMELEN, stdin);
name[strlen(name)-1] = '\0'; // strip newline
printf("%s infile \n",name);
infile = fopen(name, "r");
while (fgets(line, MAXLINELEN, infile)) {
int length = strlen(line);
line[length-1] = '\0';
linesptr[items] = line; *<- I am writing to the same mem location*
printf("the input string %d is : %s \n",items, linesptr[items]);
items++;
}
qsort(linesptr, items, MAXLINELEN, strcmp);
printf("Enter a destination filename: ");
fgets(name, sizeof(name), stdin);
name[strlen(name)-1] = '\0'; // strip newline
outfile = fopen(name, "w");
for (i=0; i<items; i++) {
fputs(linesptr[i], outfile);
}
fclose(infile);
fclose(outfile);
}
PROBLEM
I am copying the pointer address into the nth cell of the array linesptr where nth is the value=items (Here is the reference line from the code: linesptr[items] = line;). so when you print the final answer, I am referencing the same memory address to the buffer named line, the memory location at line will always point to the most recent fgets(). I understand the error but I do not know how to fix the issue. I would appreciate any help to fix the bug in the code.
Copy the line to a dynamically-allocated string.
while (fgets(line, MAXLINELEN, infile)) {
int length = strlen(line);
if (length > 0 && line[length-1] == '\n') {
line[length-1] = '\0';
length--;
}
char *linecopy = malloc(length+1);
strcpy(linecpy, line);
linesptr[items] = linecpy;
printf("the input string %d is : %s \n",items, linesptr[items]);
items++;
}
And if you want to handle more than MAXITEMS lines, you should allocate linesptr using malloc() as well. When you get to the current size of linesptr you can use realloc() to make it longer. See Read unknown number of lines from stdin, C for detailed code.
See How to qsort an array of pointers to char in C? for the proper way to sort an array of pointers to strings.
You ask for a example, so here it is:
the following proposed code:
is written for readability
checks for and handles error conditions
makes use of getline() and realloc()
is not as efficient as it could be because it calls realloc() for every line in the source file.
properly/safely uses strcspn() for removing any (possible) trailing newline characters
could have simplified the code by extracting the 'cleanup' to a sub function rather than repeating the same 'cleanup' code when ever an error was encountered.
used size_t rather than int for indexes into arrays to avoid implicit conversions
minimized the scope of variables where possible
passes proper third parameter to qsort()
properly implements the compare() helper function for qsort()
and now, the proposed code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXNAMELEN 1024
// prototypes
int compare(const void *, const void *);
int main( void )
{
printf("Enter a source filename: ");
char name[ MAXNAMELEN ];
if( !fgets(name, sizeof( name ), stdin) )
{
perror( "fgets for input file name failed" );
exit( EXIT_FAILURE );
}
// implied else, fgets for input file name successful
name[strcspn( name, "\n" ) ] = '\0'; // strip newline
printf("%s infile \n",name);
FILE *fp_in = fopen(name, "r");
if( !fp_in )
{
perror( "fopen for input file failed" );
exit( EXIT_FAILURE );
}
// implied else, fopen for input file successful
char **linesarray = NULL;
size_t numLines = 0;
char *line = NULL;
size_t lineLen = 0;
while( getline( &line, &lineLen, fp_in ) != -1 )
{
char ** temp = realloc( linesarray, (numLines+1) * sizeof( char* ) );
if( !temp )
{
perror( "realloc failed" );
fclose( fp_in );
for( size_t i = 0; i< numLines; i++ )
{
free( linesarray[i]);
}
free( linesarray );
exit( EXIT_FAILURE );
}
// implied else, realloc successful
linesarray = temp;
linesarray[ numLines ] = line;
numLines++;
// prep for next iteration
line = NULL;
lineLen = 0;
}
free( line );
fclose( fp_in );
//puts( "all file read in" );
qsort( linesarray, numLines, sizeof( char * ), compare );
//puts( "file sorted" );
printf("Enter a destination filename: ");
if( !fgets(name, sizeof(name), stdin) )
{
perror( "fgets for output file name failed" );
for( size_t i = 0; i< numLines; i++ )
{
free( linesarray[i]);
}
free( linesarray );
exit( EXIT_FAILURE );
}
// implied else, fgets() for output file name successful
name[strcspn( name, "\n" ) ] = '\0'; // strip newline
FILE *fp_out = fopen(name, "w");
if( !fp_out )
{
perror( "fopen for output file failed" );
for( size_t i = 0; i< numLines; i++ )
{
free( linesarray[i]);
}
free( linesarray );
exit( EXIT_FAILURE );
}
// implied else, fopen for output file successful
for (size_t i=0; i<numLines; i++)
{
if( fputs(linesarray[i], fp_out ) == EOF )
{
perror( "fputs failed" );
fclose( fp_out );
for( size_t i = 0; i< numLines; i++ )
{
free( linesarray[i]);
}
free( linesarray );
exit( EXIT_FAILURE );
}
}
fclose( fp_out );
for( size_t i = 0; i< numLines; i++ )
{
free( linesarray[i]);
}
free( linesarray );
}
int compare(const void *ls, const void *rs )
{
char *leftSide = *(char**)ls;
char *rightSide = *(char**)rs;
return strcmp( leftSide, rightSide );
}
Here is the complete working solution to read in a file (big data), sort it and write it to a file:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#define MAXNAMELEN 1000
#define MAXLINELEN 5000
#define MAXITEMS 100000
char* linesptr[MAXITEMS];
int compare_function(const void *name1, const void *name2)
{
const char *name1_ = *(const char **)name1;
const char *name2_ = *(const char **)name2;
return strcmp(name1_, name2_);
}
int
main(int argc, char ** argv)
{
FILE * infile, * outfile;
char name[MAXNAMELEN];
char line[MAXLINELEN];
int i, items = 0;
printf("Enter a source filename: ");
fgets(name, MAXNAMELEN, stdin);
name[strlen(name)-1] = '\0'; // strip newline
infile = fopen(name, "r");
while (fgets(line, MAXLINELEN, infile)) {
int length = strlen(line);
line[length-1] = '\0';
char *linecopy = malloc(length);
strcpy(linecopy, line);
linesptr[items] = linecopy;
items++;
}
qsort(linesptr, items, sizeof(char *), compare_function);
printf("Enter a destination filename: ");
fgets(name, sizeof(name), stdin);
name[strlen(name)-1] = '\0'; // strip newline
outfile = fopen(name, "w");
for (i=0; i<items; i++) {
fprintf(outfile, "%s\n", linesptr[i]);
}
fclose(infile);
fclose(outfile);
}

How to copy the returned token by strtok in c

When I try to copy the strtok through strcpy as suggested by the other answers on this forum. I don't get the respective number. File format is something like this 43,789,127.0.0.1 on each particular line. However I get 127 in the temp[2] location which should be 127.0.0.1 . What am I missing over here?
FILE *f = fopen("somefile", "r");
char *temp[3];
temp[0] = malloc(20);
temp[1] = malloc(20);
temp[2] = malloc(20);
const char s[1] = ",";
char *pch;
if(f != NULL)
{
char line[1024];
while(fgets(line, sizeof line, f) != NULL)
{
pch = strtok(line, s);
for(int i = 0; i<3; i++)
{
strcpy(temp[i],pch);
pch = strtok (NULL, s);
}
}
fclose(f);
} else
{
perror("somefile");
}
for(int i = 0; i<3; i++)
{
printf ("%s\n",temp[i]);
}
s is not a proper C string: const char s[1] = ","; defines it to have a size of 1, without a null terminator.
Use this instead:
const char *s = ",";
Note that a line with fewer than 2 commas will cause the program to have undefined behavior as you do not check that strtok() returns a non NULL pointer. Here is an alternative using sscanf():
#include <stdio.h>
int main(void) {
FILE *fp = fopen("somefile", "r");
char temp[3][20];
if (fp != NULL) {
char line[1024];
while (fgets(line, sizeof line, fp) != NULL) {
if (sscanf(line, "%19[^,],%19[^,],%19[^\n]", temp[0], temp[1], temp[2]) == 3) {
printf("%s\n%s\n%s\n\n", temp[0], temp[1], temp[2]);
}
}
fclose(fp);
}
return 0;
}
Note however that the above code will fail to parse lines with empty fields such as ,, because sscanf() requires a non empty string for the %[^,] conversion specifier.
Note also that strtok() would be inappropriate for such parsing too as it treats sequences of separators as a single separator, which is OK for white space but probably incorrect for ,.
the following proposed code:
cleanly compiles
is consistently indented
is appropriately horizontally and vertically spaced
corrects all the known problems in the posted code
properly checks for and handles errors
properly displays the parameters from all the lines in the file
eliminates unneeded variables
and now the code
#include <stdio.h> // fopen(), fclose(), fgets(), perror()
#include <stdlib.h> // exit(), EXIT_FAILURE
#include <string.h> // strtok(), strcpy()
#define MAX_LENGTH 20
#define MAX_PARAMETERS 3
int main( void )
{
FILE *f = fopen( "somefile", "r" );
if( !f )
{
perror( "fopen to read somefile failed" );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
char *temp[ MAX_PARAMETERS ];
if( NULL == ( temp[0] = malloc( MAX_LENGTH ) ) )
{
perror( "malloc failed" );
exit( EXIT_FAILURE );
}
if( NULL == ( temp[1] = malloc( MAX_LENGTH ) ) )
{
perror( "malloc failed" );
exit( EXIT_FAILURE );
}
if( NULL == ( temp[2] = malloc( MAX_LENGTH ) ) )
{
perror( "malloc failed" );
exit( EXIT_FAILURE );
}
char line[1024];
while( fgets(line, sizeof line, f) )
{
int i;
char *pch = strtok( line, "," );
for( i = 0; i<3 && pch; i++ )
{
strcpy( temp[i], pch );
pch = strtok ( NULL, "," );
}
if( MAX_PARAMETERS != i )
{
printf( "failed to extract all parameters from line: %s\n", line );
}
else
{
for( int j = 0; j<MAX_PARAMETERS; j++ )
{
printf( "%s\n", temp[j] );
}
}
}
fclose( f );
} // end function: main

Printing 60 characters per line

I have written a program that gets a text file from a user.
It should then print 60 characters a time then start on a new line, however, even though it works
some words go over this limit and then it cuts the word into half then starts
again on a new line. So I need my program to essentially figure out
whether that word would fit into the 60 character limit so no words are split up.
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
char ch, file_name[25];
FILE *fp;
printf("Enter file name: \n");
scanf("%24s" ,file_name);
if ( (fp = fopen(file_name,"r")) == NULL ){
perror("This file does not exist\n");
exit(EXIT_FAILURE);}
int c, count;
count = 0;
while ( (c = fgetc(fp)) != EOF ) {
if ( c == '\n' )
putchar( ' ' );
else
putchar( c );
count++;
if ( count == 60 ) {
putchar( '\n' );
count = 0;
}
}
putchar( '\n' );
fclose(fp);
}
#include <stdio.h>
#include <stdlib.h>
int readWord(FILE *fp,char *buff,char *lastChar){
char c;
int n=-1;
*buff=0;
*lastChar=0;
while((c= fgetc(fp))!=EOF){
n++;
if(isspace(c)){
/*
you may keep tabs or replace them with spaces
*/
*lastChar=c;
break;
}
buff[n]=c;
buff[n+1]=0;
}
return n;
}
int main( void ) {
char ch, file_name[25];
char buff[50];
int pos=0;
FILE *fp;
printf("Enter file name: \n");
gets(file_name);
if ( !(fp = fopen(file_name,"r")) ) {
perror("This file does not exist\n");
exit(EXIT_FAILURE);
}
int c, count;
count = 0;
while ( (pos=readWord(fp,buff,&ch))!=EOF) {
count+=pos+(!!ch);
if(count>60){
printf("\n");
count=pos;
}
if(ch){
printf("%s%c",buff,ch);
}else{
printf("%s",buff);
}
if(!pos){
count=0;
}
}
putchar( '\n' );
fclose(fp);
return 0;
}
You could scan a word and if the line and word are less than 60, concatenate them. Otherwise print the line and copy the word to the line starting the process over again.
#include <stdio.h>
#include <string.h>
int main(void) {
FILE *fp = NULL;
char file_name[257] = {'\0'};
char line[61] = {'\0'};
char word[61] = {'\0'};
int out = 0;
printf ( "Enter file name:\n");
scanf ( " %256[^\n]", file_name);
if ( ( fp = fopen ( file_name, "r")) == NULL) {
printf ( "could not open file\n");
return 1;
}
while ( ( fscanf ( fp, "%60s", word)) == 1) {
if ( strlen ( line) + strlen ( word) + 1 <= 60) {
strcat ( line, " ");
strcat ( line, word);
out = 0;
}
else {
printf ( "%s\n", line);
strcpy ( line, word);
out = 1;
}
}
if ( !out) {
printf ( "%s\n", line);
}
fclose ( fp);
return 0;
}

reading words/strings from file+length of them - c

i have a problem with my c program,
it should read words/strings from txt file, then count length of them.
when i run my program, it doesnt response
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *f;
char c;
char word[50];
int a,b=0;
if ((f = fopen("file.txt", "r")) == NULL)
{
printf("CANT OPEN THE FILE" "\n");
return 1;
}
while((c=fgetc(f))!=EOF){
if (c==' ')b++;
word[b]=word[b]+c;
}
for (a=0;a<b;a++){
printf("%c ",word[0]);
}
return 0;
}
it should do this: first i open my file, then i will read every char from this file+storing this chars in array word, then when blank space occurs(' '), it should write chars to next index of array, so the words will be created on different indexes of array
then it should count the lenght of words, but that should be easy to implement, thx a sorry for my english
They are ALOT of errors with the code you shared :
J is not declared, so you need to add int j = 0; I'm assuming than j is the number on whitespace on your doc.
word[b]=word[b]+c; get changed into word[b]= c;
You add an incremntation on b in your loop then, so you wont write only on word[0].
Your printing is bad aswell, you would only show the first letter over and over.
This is the final code, corrected. It shows the entire file if the file is less than 200 caracters. J is the number of whitespace.
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *f;
char c;
char word[200];
int a,b=0;
int j = 0;
if ((f = fopen("file.txt", "r")) == NULL)
{
printf("CANT OPEN THE FILE" "\n");
return 1;
}
while((c=fgetc(f))!=EOF){
if (c==' ')j++;
word[b]= c;
b++;
}
for (a=0;a<b;a++){
printf("%c",word[a]);
printf("The file contains %d caracters, and %d whitespaces", b, j);
}
return 0;
}
By the way, next time. try to compile at least. It's clear that you put no effort into it before submitting a question here on SO.
the following compiles and meets your description of what needs to be done
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // memset
#define MAX_WORD_LENGTH (50)
struct wordStruct_t
{
char word[MAX_WORD_LENGTH];
};
int main()
{
FILE *fp;
int c;
char word[50]; // assume max word length is < 50
int i = 0; // word byte index
int wordCount = 0; // count of words read
struct wordStruct_t * wordArray = NULL;
char * testArray = NULL;
if ((fp = fopen("file.txt", "r")) == NULL)
{
perror( "fopen failed for read of file.txt");
exit( EXIT_FAILURE );
}
// implied else open successful
memset( word, 0x00, sizeof( word ) );
while((c=fgetc(fp))!=EOF)
{
if( (c!=' ') && (c != '\n') )
{ // then letter to add to current word (should also check for word overflow)
word[i++] = c;
}
else
{ // else, end of word found
// allocate max room for new word
if( NULL == (testArray = realloc( wordArray, sizeof(struct wordStruct_t) * (wordCount+1)) ) )
{
perror( "realloc failed");
free( wordArray );
fclose( fp );
exit( EXIT_FAILURE );
}
// implied else, realloc successful
wordArray = (struct wordStruct_t*)testArray;
strcpy( wordArray[wordCount].word, word );
memset( word, 0x00, sizeof(word) ); // prep for next word
} // end if
} // end while
for (i = 0; i< wordCount; i++)
{
printf("word: %d is %s and contains %d bytes\n",
i,
wordArray[i].word,
(int)strlen(wordArray[i].word ) );
}
free( wordArray );
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h> //for string functions
int main()
{
FILE *f;
int c; //c should be an int
char word[50];
char *ptr; //to store each word
int a,b=0;
if ((f = fopen("file.txt", "r")) == NULL)
{
printf("CANT OPEN THE FILE" "\n");
return 1;
}
while((c=fgetc(f))!=EOF){
word[b++]=c;
}
for (a=0;a<b;a++){
printf("%c ",word[a]); //word[a] not word[0]
}
ptr=strtok(word," ");//get first word
a=0;
while(ptr!=NULL)
{
printf("Word %d which is %s is %d letters long",++a,ptr,strlen(ptr));
ptr=strtok(NULL," "); //get next word
}
return 0;
}

Resources