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;
}
Related
i'm trying to fill each row of the array with each word of the file.
I don't want to overallocate memory , so i want to know atleast the lenght of the longest word and the number of rows i should allocate, so the number of words written in the file.
I can't understand where is the problem in the code. I think it should be a problem with counting the longest word since when i print longest_file_word after assigning the value returned by the function it prints -1.
Obviously it doesnt work.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int longestWord(char *file, int *nWords);
char ** Create2DStr(ssize_t numStrings, ssize_t maxStrLen);
int main(int argc, char *argv[]){
int file_elements_number=0 , i , j , k , z , longest_file_word , count_file_words ;
char *filename =(char*)malloc((strlen(argv[2]) +1 )*sizeof(filename));
strcpy( filename , argv[1]);
for(i = 0; i < strlen(argv[1])+1 ; i++){
printf("%c" , filename[i]);
}
if(filename = NULL){
printf("Non c'e' abbastanza memoria");
return 1;
}
if(argc!=2)
{
printf("Errore numero parametri passati da linea di comando\n");
return 1;
}
longest = longestWord( filename , &count);
printf("ciao %d\n%d\n", count , longest);
char **file_words = Create2DStr(count, longest);
FILE *file_ptr;
const char delim[] = {" \n\t"};
char line[260];
char *buf = NULL;
file_ptr = fopen( filename, "r");
count=0;
while(fgets(line, 260, file_ptr))
{
buf = strtok(line, delim);
while(buf)
{
if((strlen(buf) > 0)){
strcpy(file_words[count], buf);
count++;
}
buf = strtok(NULL, delim);
}
}
for(i = 0 ; i < count ; i++){
for( j = 0 ; j < longest ; j++){
printf("%c" , file_words[i][j]);
}
printf("\n");
}
fclose(file_ptr);
free(filename);
filename = NULL;
return 0;
}
int longestWord(char *filename, int *nWords)
{
FILE *file_ptr=0;
int cnt=0, longest=0, numWords=0;
char c;
file_ptr = fopen(filename, "r");
if(file_ptr){
while ( (c = fgetc(file_ptr) ) != EOF )
{
if ( isalnum (c) ) {
cnt++;
}
else if ( ( ispunct (c) ) || ( isspace(c) ) || (c == '\0' ) || (c== '\n'))
{
(cnt > longest) ? (longest = cnt, cnt=0) : (cnt=0);
numWords++;
}
}
*nWords = numWords;
fclose(file_ptr);
}
else {
return -1;
}
return longest;
}
char ** Create2DStr(ssize_t numStrings, ssize_t maxStrLen){
int i;
char **a = {0};
a =(char**) calloc(numStrings, sizeof(a));
for(i=0;i<numStrings; i++)
{
a[i] = (char*)calloc(maxStrLen + 1, 1);
}
return a;
}
You're doing,
if(filename = NULL)
rather than,
if(filename == NULL)
after reading your filename.
You should be compiling with warnings turned on, -Wall on gcc.
The result -1 means that function longestWord cannot open the specified file name which may be a result of the if(filename = NULL)
Apart from this it is difficult to understand what you are doing with argv[1] and argv[2] to prepare filename. You allocate memory based on the string length of argv[2], then copy the string from argv[1] which could be longer.
You should do the checks of argc and filename before you access argv or filename.
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
I am currently collecting input from a file but my program separates each letter into the char array instead of each word. How can I change my code to get each word?
char c, fileName[20];
FILE *f;
void getFile() {
f = fopen(fileName, "r");
while((c = fgetc(f)) != EOF) {
printf("%c",c);
}
fclose(f);
}
You can use a scanset with fscanf or sscanf. This scanset, %29[a-zA-Z], reads lower and upper case English characters and stops when it encounters a character not in the set. The 29 limits the maximum number of characters to read so as to not overwrite the buffer, word[30]. When fscanf fails, the else will read one character from the file and give fscanf another try at reading another word.
This also uses the command line to pass in the file to read as argv[1].
#include <stdio.h>
#include <stdlib.h>
int main( int argc, char *argv[])
{
char word[30] = {'\0'};
int ch = 0;
FILE *pf = NULL;
if ( argc != 2) {//command requires program name and a file name
printf ( "useage: program filename\n");
return 1;
}
if ( ( pf = fopen ( argv[1], "r")) == NULL) {
perror ( "could not open file");
return 1;
}
while ( 1) {
if ( ( fscanf ( pf, "%29[a-zA-Z]", word)) == 1) {
printf ( "%s\n", word);
}
else {
if ( ( ch = fgetc ( pf)) == EOF) {//read one character and check for end of file
break;
}
//could do something here with the value of ch if needed
}
}
printf ( "--DONE--\n");
return 0;
}
This will allocate an array for each word. As words are added the array is expanded using realloc.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main( int argc, char *argv[])
{
char **words = NULL;//pointer for words
char **temp = NULL;
char word[30] = {'\0'};
int ch = 0;
int each = 0;
int found = 0;
int count = 0;
int wordsize = 0;
FILE *pf = NULL;
if ( argc != 2) {//command requires program name and a file name
printf ( "useage: program filename\n");
return 1;
}
if ( ( pf = fopen ( argv[1], "r")) == NULL) {
perror ( "could not open file");
return 1;
}
while ( 1) {
if ( ( fscanf ( pf, "%29[a-zA-Z]", word)) == 1) {
found = 0;
for ( each = 0; each < wordsize; each++) {
if ( strcmp ( words[each], word) == 0) {
found = 1;
break;
}
}
if ( found == 0) {
wordsize += 1;// increment number of words
temp = realloc ( words, wordsize * sizeof ( char *));//reallocate for another word
if ( temp != NULL) {
words = temp;
words[wordsize - 1] = malloc ( strlen ( word) + 1);//malloc for the word itself
if ( words[wordsize - 1] != NULL) {
strcpy ( words[wordsize - 1], word);
}
else {
printf ( "malloc failed\n");
wordsize -= 1;
break;
}
}
else {
printf ( "realloc failed\n");
wordsize -= 1;
break;
}
}
printf ( "%s\n", word);
}
else {
if ( ( ch = fgetc ( pf)) == EOF) {//read one character and check for end of file
break;
}
//something could be done with ch if needed
}
}
printf ( "--DONE Reading file--\n");
for ( each = 0; each < wordsize; each++) {// print each word
printf ( "%s\n", words[each]);
}
count = 0;
printf ( "Enter a word to search for\n");
if ( ( scanf ( "%29[a-zA-Z]", word)) == 1) {
for ( each = 0; each < wordsize; each++) {
if ( strcmp ( words[each], word) == 0) {
printf ( "Found %s at index %d\n" word, each);
count++;
}
}
printf ( "Found %s %d times\n" word, count);
}
for ( each = 0; each < wordsize; each++) {//release memory
free ( words[each]);
}
free ( words);
return 0;
}
You could use char * fgets ( char * str, int num, FILE * stream );
Then use char *strtok(char *str, const char *delim)
for example
#include <stdio.h>
int main()
{
FILE * pFile;
char mystring [100];
const char delimters[2] = " ,:";
char *token;
pFile = fopen ("myfile.txt" , "r");
if (pFile == NULL) perror ("Error opening file");
else {
if ( fgets (mystring , 100 , pFile) != NULL )
/* get the first token */
token = strtok(mystring, delimiters);
/* walk through other tokens */
while( token != NULL )
{
printf( " %s\n", token );
token = strtok(NULL, delimiters);
}
fclose (pFile);
}
return 0;
}
Use fscanf(3) instead
char word[256], *p;
while(fscanf(f, "%s", &word) != EOF) {
printf("%s\n", word);
/* break down word into individual chars */
for(p=word; *p; p++) {
printf("%c ", *p);
}
printf("\n");
}
First problem fgetc() returns an int you cannot store EOF in a char variable.
You should check if fopen() didn't return NULL.
You can use this technique to read words like this
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAX_BUFFER_SIZE 256
char **load_words_from_file(const char *filename)
{
size_t wordcount;
size_t charcount;
char buffer[MAX_BUFFER_SIZE];
int chr;
FILE *file;
char **words;
void *pointer;
file = fopen(filename, "r");
if (file == NULL)
return NULL;
wordcount = 0;
charcount = 0;
words = NULL;
while ((chr = fgetc(file)) != EOF)
{
/* it's a white space or it exceeded buffer size, it's a word delimiter */
if ((isspace(chr) != 0) || (charcount >= sizeof(buffer) - 1))
{
/* 'nul' terminate 'buffer' for strcpy() and strlen() */
buffer[charcount] = '\0';
pointer = realloc(words, (1 + wordcount) * sizeof(char *));
if (pointer == NULL) /* failure, free allocated memory and return NULL */
goto failure;
words = pointer;
words[wordcount] = malloc(1 + charcount);
charcount = 0; /* reset character count */
if (words[wordcount] == NULL)
goto failure;
strcpy(words[wordcount], buffer);
wordcount += 1;
}
else
{
/* store the character and count it */
buffer[charcount] = (char)chr;
charcount += 1;
}
}
pointer = realloc(words, (1 + wordcount) * sizeof(char *));
if (pointer == NULL)
goto failure;
words = pointer;
words[wordcount] = NULL; /* this will let you know when to stop fetching words */
fclose(file);
return words;
failure:
for (size_t i = 0 ; i < wordcount ; ++i)
free(words[i]);
free(words);
return NULL;
}
int
main()
{
const char *filename = "your-file-name-here";
char **words = load_words_from_file(filename);
size_t counter = 0;
if (words == NULL)
{
printf("no words found in the file\n");
return -1;
}
while (words[counter] != NULL)
{
printf("%zuth word: %s\n", 1 + counter, words[counter]);
free(words[counter]); /* this program will not use it again */
counter += 1;
}
free(words);
return 0;
}
the strtok() method would also work, but it's harder to understand.
Note the use of goto, it's a benign usage, although some people think that goto is always harmful, that's not true, using it like this makes the program adhere to the DRY priniciple.
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;
}
i have project in C that tells me to read a file and save each line in a string table stateTable[10][50],and i dont know how to do it,can anyone help me?
All i have come up with for now is:
int i=0,j=0,x=10,y=50;
char stateTable [ 10 ][ 50 ];
static const char filename[] = "file.txt";
FILE *file = fopen ( filename, "r" );
if ( file != NULL )
{
while ( fgets ( stateTable[i], y , file ) != NULL )
{
i++;
}
fclose ( file );
}
else
{
perror ( filename );
}
return 0;
Although i dont know if by putting stateTable[i] in gets is correct,and if so will each string which is saved in the stateTable[10][50] have \0 at the end?
#include <stdio.h>
#include <string.h>
int main(void)
{
int j, i = 0;
const int y = 50, x= 10;
char stateTable [ x][ y ];
const char filename[] = "file.txt";
FILE *file = fopen ( filename, "r" );
if ( file != NULL )
{
while ( fgets ( stateTable[i], y , file ) != NULL )
{
i++;
if (i > x)
break;
}
fclose ( file );
}
else
{
perror ( filename );
}
for (j=0 ; j < i; j++)
{
printf ( "\nstateTable[j] %s len = %zu",
stateTable[j], strlen (stateTable[j]));
}
printf ("\n");
return 0;
}
As seen from the printf statement in the end it shows that the code works.
The strlen shows that the \0 is inserted.
Mind that the fgets retains the linefeed in the string.