How to save a file's lines in a string table? - c

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.

Related

Function that copies parts of a file to another in C

I have to make a function which reads a file line by line and copies a some of them to another file. The head of the function has to look like this: "int write_x(const char *input_path, const char *output_path, int x)" and can't be changed. For example if x = 3 every third line of the input txt-file should be copied to the output txt-file. Every line has a maximum of 80 signs. I hope someone can help me because i'm not programming very long yet.
This is what I have alreaday, but it doesn't work:
#include <stdlib.h>
#include <stdio.h>
int write_x(const char *input_path, const char *output_path, int x){
input_path = "in.txt";
output_path = "out.txt";
FILE *in
FILE *out
char text[100];
for(int i = 0; i < 100; i++){
fgets(text[i], 80, in);
if(i % x == 0) {
fprintf(out, "%s\n", text[i]);
}
}
return 0;
}
I didn't compile it (I'll leave that to you), but how about something like this?
Note that if your teacher penalizes for the use of 'goto', then you'll need to modify the error handling.
#include <stdio.h>
#include <stdlib.h>
int write_x(const char *input_path, const char *output_path, int x) {
int result = 0 ;
FILE * inputFile=NULL;
FILE * outputFile=NULL;
/* Open the input file for reading */
inputFile = fopen( input_path, "r" ) ;
if ( inputFile == NULL ) {
perror( "fopen(input_path)" ) ;
result = -1;
goto clean_up;
}
/* Open the output file for writing */
outputFile = fopen( output_path, "w") ;
if ( outputFile == NULL ) {
perror( "fopen(output_path)" ) ;
result = -1;
goto clean_up;
}
int lineNumber = 0 ;
char * lineBuffer = NULL ; // memory will be allocated by getline()... but you'll need to free it up afterwards
int lenBuffer ; // getline will set how bug the buffer is
/* Repeat for each line read */
while (getline( &lineBuffer, &lenBuffer, inputFile) != -1) {
/* Only at each 'x' line count */
if ( (++lineNumber % x ) == 0 ) {
/* Write the line to the output file */
if ( fwrite( lineBuffer, lenBuffer, 1, outputFile ) != lenBuffer ) {
perror("fwrite");
result = -1;
goto clean_up;
}
}
}
clean_up:
/* avoid memory leak */
if ( lineBuffer != NULL ) {
free( lineBuffer ) ;
}
/* Close the input file */
if ( inputFile != NULL ) {
fclose( inputFile ) ;
}
/* Close the output file */
if ( outputFile != NULL ) {
fclose( outputFile ) ;
}
/* All done */
return result ;
}
It seems like a really bad design to be passing paths to this function as arguments instead of FILE *'s, but you're under no obligation to read the file line by line. Just read one character at a time. Something like:
#include <stdlib.h>
#include <stdio.h>
FILE * xfopen(const char *path, const char *mode);
int
write_x(const char *input_path, const char *output_path, int x)
{
FILE *in = xfopen(input_path, "r");
FILE *out = xfopen(output_path, "w");
int c;
int count = 1;
while( (c = fgetc(in)) != EOF ){
if( count == x ){
fputc(c, out);
}
if( c == '\n' ){
count = ( count % x ) + 1;
}
}
return 0;
}
int
main(int argc, char **argv)
{
int step = argc > 1 ? strtol(argv[1], NULL, 10) : 1;
char *in = argc > 2 ? argv[2] : "in.txt";
char *out = argc > 3 ? argv[3] : "out.txt";
write_x(in, out, step);
return 0;
}
FILE *
xfopen(const char *path, const char *mode)
{
FILE *fp = path[0] != '-' || path[1] != '\0' ? fopen(path, mode) :
*mode == 'r' ? stdin : stdout;
if( fp == NULL ){
perror(path);
exit(EXIT_FAILURE);
}
return fp;
}

How to read from a file.csv and save every value in a string of array C

I have a file with 6.321.078 records, they are formed by couple of integers separated by a comma. My aim is to read line by line and save it inside a char array (so, strings). My trouble is , when I run sscanf() it doesn't work. I think that this is the problem but I'm not sure that is the only one. I know that the file contain INT, but I need to save every line such as string. What can I do and why does not it work? (There is an example of my file.csv below)
main.c:
int main() {
FILE *fd;
char *arr;
arr = (char *)malloc(6321078);
for (int k = 0; k < 6321078; k++) {
arr[k] = calloc(20, sizeof(char));
}
char *r;
int pos = 0;
int n;
fd = fopen("file.csv", "r");
if (fd == NULL) {
perror("Error");
exit(1);
}
while (fgets(r, sizeof(r), fd) != NULL) {
sscanf(r, "%s", arr[pos]);
printf("%s", arr[pos]);
pos++;
}
}
Example of file.csv:
A pointer to array of 20 could be used char (*arr)[20]
Then allocate memory for the number of records.
Use fgets to read directly from the file into each record.
When done, close the file and free the memory.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 6321078
#define LEN 20
int main ( void) {
char (*arr)[LEN] = NULL;
int pos = 0;
FILE *fd = NULL;
if ( NULL == ( fd = fopen("file.csv", "r"))) {
perror("Error");
exit ( EXIT_FAILURE);
}
if ( NULL == ( arr = calloc ( SIZE, sizeof *arr))) {
fclose ( fd);
fprintf ( stderr, "calloc problem\n");
exit ( EXIT_FAILURE);
}
while ( pos < SIZE && fgets ( arr[pos], sizeof arr[pos], fd)) {
printf ( "%s", arr[pos]);
++pos;
}
fclose ( fd);
free ( arr);
return 0;
}

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

how to make a char into one word in C

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.

How to make this transposing algorithm read a whole text file

So I've been trying to write a transposing algorithm where each character’s position is shifted to a new location within a file. For example if the key is 3 and the character array is
"This program is supposed to encrypt a file."
after encrypting, the output will be
"Tsrr ps cpai.h oaispetert lipgmsuodony fe"
The problem is that after it's done encrypting the first line of a file, it stops and doesn't continue encrypting the whole file. after compiling, it can be executed like this
./executable -e 3 inputfile outputfile
.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 200
int main ( int argc, char* argv[ ] ) {
int pos = 0;
char characters[ BUFFER_SIZE ];
int index, k, size, key;
char* echars;
FILE* input;
FILE* output;
if ( argc == 5 ) {
// exits if key is lower than 1
key = atoi ( argv[ 2 ] );
if ( key < 1 ) {
perror ( "Error: This value cannot be used as a key" );
exit ( EXIT_FAILURE );
}
input = fopen ( argv[ 3 ], "r" );
//Shows error if there's no file
if ( input == NULL ) {
perror ( "Error, File doesn't exits" );
exit ( EXIT_FAILURE );
}
output = fopen ( argv[ 4 ], "w" );
fgets (characters, BUFFER_SIZE, input);
fseek (input, 0, SEEK_END);
size = ftell ( input );
echars = ( char* ) malloc ( size );
if ( strcmp ( argv[ 1 ], "-e" ) == 0 ) {
while (strlen(characters) && characters[strlen(characters)-1] == '\n'){
characters[strlen(characters)-1] = '\0';
for (index = 0; index < key; index++) {
for (k = index; k < strlen( characters ); k += key)
echars[ pos++ ] = characters[ k ];
}
printf("Successfuly encrypted\n");
}
} else if( strcmp ( argv[ 1 ], "-d" ) == 0 ) {
for (index = 0; index < key; index++) {
for (k = index; k < strlen( characters ); k += key)
echars[ k ] = characters[ pos++ ];
}
printf("Successfuly decrypted\n");
}
fputs( echars, output );
fclose ( input );
fclose ( output );
} else {
perror("Too few arguments, something went wrong\n");
printf("Usage: ./program -e (encrypts) or -d (decripts) 3 (key) inputfile destinationfile\n");
printf("Example:'./exectutable -e 3 inputfile.txt outputfile.txt\n");
exit ( EXIT_FAILURE );
}
return 0;
}
fgets stops reading when it hits a newline.
You need to either put a loop around it or use a read operation that can read larger chunks.

Resources