I am having a problem while trying to print to txt file from global array of char*.
My array is declared as
char* codes[256];
also i have a function that construct a string and returns it to after which that value is placed into this global array
char* printArr(int arr[], int n)
{
char* code = (char *) malloc(sizeof(char) * (n+1));
int i;
for (i = 0; i < n; ++i)
{
code[i] = arr[i] + '0';
}
code[n] = '\0';
return code;
}
after which I just simply place that value into that global array. After that I am trying to print that array values into a txt file like this :
void PrintToFile(char* outputFileName)
{
FILE* f = fopen(outputFileName, "w+");
int i;
for (i = 0; i < 256; ++i)
{
//printf("%s\n", codes[i]);
fprintf(f, "%s\n", codes[i]);
}
fclose(f);
}
But for some reason my txt file turns out blank.
Also without opened stream when I try to print to stdout i get those values but with both printf and fprintf I don't get anything out either on stdout or in txt file.
Thanks in advance!
Related
I try to read a file line by line to that dynamic array:
//r = rows (max. chars of one line), c = column (lines of file)
char *file_content[r];
for (int i=0; i<r; i++) {
file_content[i] = (char*)calloc(c,sizeof(char));
}
readfile.c
void readFile(char *file_name, char **file_content) {
char const* const fileName = file_name;
FILE* file = fopen(fileName, "r");
int i = 0;
while(fgets(file_content[i], 512 + 1, file)) { //512+1 for null termination
/* get rid of ending \n from fgets */
file_content[i][strlen(file_content[i]) - 1] = '\0';
i++;
}
fclose(file);
}
So this code works perfectly with a static array like file_content[500][500] but with my dynamic array from above a
printf("%s", file_content[0]);
prints random content of the file.
I don't know how I should debug my problem, I'm a beginner..
this is driving me crazy. I'm trying to parse from a txt file every sentence (that is all characters between dots) and insert each sentence into an array. The end goal is to have a multi dimensional array with each sentence as single array.
I managed to reach a point where I think it should work but I'm getting a segmentation fault (core dumped) error from the line numOfRow++
void parseRows(FILE* file){
int c;
int numOfRow = 0;
int numOfChar = 0;
int numOfRows = countNumOfRows(file);
fseek(file, 0, SEEK_SET); // Reset file pointer position to the beginning
char **rows = malloc(numOfRows*sizeof(char*));
for (int i=0; i < numOfRows; i++) rows[i] = malloc(1000*sizeof(char));
while ((c=fgetc(file))!= EOF) {
if (c != '.') {
rows[numOfRow][numOfChar] = c;
numOfChar++;
} else {
rows[numOfRow][numOfChar] = '\0';
numOfRow++; // This is throwing the error
numOfChar = 0;
}
}
printOutput(rows, numOfRows);
}
If I comment out that line the program overwrites every line on the first array and I get only the last sentence as result so I know it's working.
What am I missing?
Complete code here:
#include <stdio.h>
#include <stdlib.h>
#define USAGE "USAGE: ./huffman <textFile.txt>\n"
FILE* openFile(char[]);
void parseRows(FILE*);
int countNumOfRows(FILE*);
void printOutput(char**, int);
int main(int argc, char** argv){
FILE* fd;
if (argc != 2) printf("%s", USAGE);
fd = openFile(argv[1]);
parseRows(fd);
}
FILE* openFile(char* file){
FILE* stream;
stream = fopen(file, "r");
return stream;
}
int countNumOfRows(FILE* file){
int i = 0;
char c;
while ((c=fgetc(file))!= EOF) {
if (c == '.') i++;
}
printf("numero di righe %d\n", i);
return i;
}
void parseRows(FILE* file){
int c;
int numOfRow = 0;
int numOfChar = 0;
int numOfRows = countNumOfRows(file);
fseek(file, 0, SEEK_SET); // Reset file pointer position to the beginning
char **rows = malloc(numOfRows*sizeof(char*));
for (int i=0; i < numOfRows; i++) rows[i] = malloc(1000*sizeof(char));
while ((c=fgetc(file))!= EOF) {
if (c != '.') {
rows[numOfRow][numOfChar] = (char)c;
numOfChar++;
} else {
rows[numOfRow][numOfChar] = '\0';
numOfRow += 1;
numOfChar = 0;
}
}
printOutput(rows, numOfRows);
}
void printOutput(char** matrix, int rows){
for (int i=0; i<rows; i++){
printf("%s", matrix[i]);
}
}
Example of input file textFile.txt:
Any text that contains more than one sentence.
This Should get parsed and return a 2 dimension array with every sentence as single array.
Your countNumOfRows() function counts the dots in a file, and you use that number to malloc space for your array. However, there are likely more characters beyond the last dot and before EOF (e.g. a CR or LF or CRLF), so you can easily write past the end of your malloc'd memory.
Try:
return (i + 1)
at the end of countNumOfRows() and see if that eliminates the segfault.
I am a beginner in C programming, and I am trying to write a simple code to read a text file and write its content into an array, then print it on console. However, I always get 0.0000, and I could not solve the problem.
#include <stdio.h>
#include <stdlib.h>
int numOfLines(FILE *fp1);
void printarr(float arr[], int size);
float *filetoArr(FILE *fp, int arrsize);
int main(int argc, const char *argv[]) {
char *fileName1 = argv[1];
FILE *fp1 = fopen(fileName1, "r");
printf("File name: %s", fileName1);
int size = numOfLines(fp1);
printf("Number of lines in the file: %d\n", size);
float *arr = filetoArr(fp1, size);
printarr(arr, size);
free(arr);
fclose(fp1);
}
void printarr(float *arr, int size) {
for (int i = 0; i < size; i++) {
printf("%f ", *(arr + i));
}
}
float *filetoArr(FILE *fp, int arrsize) {
int size = arrsize;
float *arr = (float *)malloc(sizeof(float) * size);
for (int i = 0; i < size; i++) {
fscanf(fp, "%f\n", (arr+i));
}
return (arr);
}
int numOfLines(FILE *fp1) {
int numberOfLines = 0;
char c;
do {
c = getc(fp1);
if (c == '\n') {
numberOfLines++;
}
} while (c != EOF);
return numberOfLines;
}
your numOfLines goes to the end of the file.
You have to rewind(fp1) to reset your file handle to position 0, or fscanf hits the end of the file, and doesn't read anything (check return code from fscanf: it should be 1 I bet you're getting 0 all the time)
There are multiple problems in your code:
you read the whole file in numOfLines(): you must reset the file pointer to the beginning of file with rewind(fp1); so fscanf() can read the file instead of hitting the end of file immediately.
the variable c used to read bytes from the file must be defined as an int for the test for end of file to be reliable. Otherwise, depending on whether char is signed or not by default, the EOF would never match or could potentially match the character \377 as end of file erroneously.
you do not check for failure to open the file.
Although returning 0 is implicit for function main() since C99, it is advisable to write the return 0; statement explicitly for better clarity.
I need some help with my C project:
I need to write a c program who receives 2 parameters:
1) The name of a text file(infile) which is in the same catalog
2) A number k>0
And creates 2 new files,outfile1 & outfile 2 as:
Outfile 1: k,2*k,3*k…. character of infile
Outfile 2: k,2*k,3*k…..line of infile
Example:
INFILE
Abcdefg
123456
XXXXXX
01010101
OUTFILE 1:
Cf25XX101
OUTFILE 2:
XXXXXX
I wrote some code ,but its not working. Any ideas?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char** read_lines(FILE* txt, int* count) {
char** array = NULL;
int i;
char line[100];
int line_count;
int line_length;
*count = 0;
line_count = 0;
while (fgets(line, sizeof(line), txt) != NULL) {
line_count++;
}
rewind(txt);
array = malloc(line_count * sizeof(char *));
if (array == NULL) {
return NULL;
}
for (i = 0; i < line_count; i++) {
fgets(line, sizeof(line), txt);
line_length = strlen(line);
line[line_length - 1] = '\0';
line_length--;
array[i] = malloc(line_length + 1);
strcpy(array[i], line);
}
*count = line_count;
return array;
}
int main(int argc, char * argv[]) {
char** array = NULL;
FILE* file = NULL;
const char* filename = NULL;
int i;
int line_count;
int k;
char c;
printf("ENTER ONE PHYSICAL NUMBER\n");
do{
if(k>0)
scanf("%d",&k);
else{
printf("ENTER ONE PHYSICAL NUMBER\n");
scanf("%d",&k);
}
}while(k<=0);
file = fopen("LEIT.txt", "rt");
if (file == NULL) {
printf("CANT OPEN FILE %s.\n", filename);
return 1;
}
array = read_lines(file, &line_count);
printf("ARRAY:\n");
for (i = 0; i < line_count; i++) {
printf("[%d]: %s\n", (i+1), array[i]);
}
printf("CALCULATING OUTFILE1 AND OUTFILE2\n");
printf("OUTFILE1:\n");
for(i=0;i<line_count;i++){
c=i*k;
printf("%c\n",array[c]);
}
printf("WRITING OUTFILE1 COMPLETE!\n");
printf("OUTFILE2:\n");
for(i=0;i<line_count;i++){
c=i*k;
printf("%c\n",array[c]);
}
printf("WRITING OUTFILE2 COMPLETE!\n");
return 0;
}
My actual problem is calculate and write into files (outfile1 and outfile2) the result...
You need to close file after finishing reading/writing it with fclose.
You can create and write strings to a file using fopen with correct mode.
You can output formatted string to a file by using fprintf.
It seems that you don't want to print the 0th character/line, so in the last for loop, i should start from 1 (or start from 0 but add 1 later).
array[c] is a string, not a character. So when printing it, you should use %s specifier instead of %c.
It is not a good idea using char as count in later for loops unless you know input file will be very short. signed char can only count to 127 before overflow (unsigned char can count to 255). But if you have a very long file, for example thousands of lines, this program would not work properly.
array is malloced in function char** read_lines(FILE* txt, int* count). After finish using it, you need to dealloc, or free it by calling
for (i = 0; i < line_count; i++) {
free(array[i]);
}
and followed by free(array). This avoids memory leakage.
Modified code is here. In the following code, char c is not used. This is the part where you process output files, and before return 0; in main function.
printf("CALCULATING OUTFILE1 AND OUTFILE2\n");
printf("OUTFILE1:\n");
// Since we finished using LEIT.txt, close it here.
fclose(file);
// Mode: "w" - Write file. "+" - Create if not exist.
// You can lso use "a+" (append file) here if previous record need to be preserved.
FILE *out1 = fopen("OUTFILE1.txt", "w+");
FILE *out2 = fopen("OUTFILE2.txt", "w+");
if ((out1 == NULL) || (out2 == NULL)) {
printf("CANT CREATE OUTPUT FILES.\n");
return 1;
}
// Out file 1.
unsigned int count = k;
for (i = 0; i < line_count; i++){
while (count < strlen(array[i])) {
// This just prints to stdout, but is good for debug.
printf("%c", array[i][count]);
// Write to the file.
fprintf(out1, "%c", array[i][count]);
// Calculate c for next char.
count += k + 1;
}
// Before go to next line, minus string length of current line.
count -= strlen(array[i]);
}
printf("\n");
printf("WRITING OUTFILE1 COMPLETE!\n");
// Close file.
fclose(out1);
// Out file 2.
printf("OUTFILE2:\n");
for (i = 1;i < line_count / k; i++){
count = i * k;
// This just prints to stdout, but is good for debug.
printf("%s\n", array[count]);
// Write to the file.
fprintf(out2, "%s\n", array[count]);
}
printf("WRITING OUTFILE2 COMPLETE!\n");
//Close file.
fclose(out2);
// dealloc malloced memory.
for (i = 0; i < line_count; i++) {
free(array[i]);
}
free(array);
The code I am working on reads in a dictionary of 45430 words and then prints to the file all the other words in the dictionary contained within each word. I am just working on getting the file MyDictionary txt file read into the char array word[45430][30] and then printing this to the words-in-words txt file. I run into a seg fault at 44946 word when I do so, but in the same while loop I am also printing to the console and all words print out properly. Why is it I am getting this seg fault for writing to the file? And why is there no seg fault writing to the console?
Code:
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include <string.h>
//char ***alloc_array(int,int);
int main(void){
FILE *fr; //declare file read file pointer
FILE *fp; //declare file printed file pointer
//char array to read in up to 30 chars
char line[31];
long numwords=45430; //number of words in dictionary
int maxlength=31; // the longest string in dictionary (30 chars)
long i; //counts up to 45430
//allocate space for 45430 words at a max length of 30 chars (1 extra char for "\0")
char ***word = calloc(numwords, sizeof(char **));
for(i = 0; i != numwords; i++) {
word[i] = calloc(maxlength, sizeof(char *));
}
//Open MyDictionary.txt and determine if there is an error or not
fr = fopen ("MyDictionary.txt", "r"); // open the file for reading
if(fr==NULL){
printf("\nError! opening input file");
exit(1); //Program exits if file pointer returns NULL.
}
//Open words-within-words.txt and determine if there is an error or not
fp = fopen ("words-within-words.txt", "w"); // open the file for reading
if(fp==NULL){
printf("\nError! opening output file");
exit(1); //Program exits if file pointer returns NULL.
}
int j=0; //counts to 30 for max length
i=0;
while(fgets(line, 40, fr) != NULL){ //get a line, up to 40 chars from fr and put first . done if NULL
for(j=0;j<30;){
word[i][j]=&line[j];
j++;
}
j=0;
printf("\n%s",word[i][j]); //print out each word of dictionary to console on its own line
/*
if((i>4 && i<8)||(i>45428)){
fprintf(fp,"\nanalyze:word[i][0]=%s\tword[i][2]=%s\ti=%li",word[i][0],word[i][2],i+1);
}
*/
fprintf(fp,"%s",word[i][j]); //print out each word of dictionary to words-in-words on its own line
i++;
}
fclose(fr); //close the files prior to exiting
fclose(fp);
return 0;
} //main
char ***word = calloc(numwords, sizeof(char **));
for(i = 0; i != numwords; i++) {
word[i] = calloc(maxlength, sizeof(char *));
}
You've got one too many levels of indirection. You are storing a list of words. A word is a char *, so a list of words would be char **.
char **word = calloc(numwords, sizeof(char *));
for (i = 0; i != numwords; i++) {
word[i] = calloc(maxlength, sizeof(char));
}
This will then necessitate changes to the rest of your code. You can get rid of j entirely. This:
for(j=0;j<30;){
word[i][j]=&line[j];
j++;
}
Becomes:
strcpy(word[i], line);
And this:
j=0;
printf("\n%s",word[i][j]);
fprintf(fp,"%s",word[i][j]);
i++;
Becomes:
printf("%s\n", word[i]);
fprintf(fp, "%s\n", word[i]);
'word' should be an array of pointers, so the right type is char **, not char ***.
Each entry in the array is a pointer to a buffer of characters:
char **word = (char **)calloc(numwords, sizeof(char *));
if (!word)
// exit with error
for (i = 0; i != numwords; i++) {
word[i] = (char *)calloc(maxlength, sizeof(char)); // just allocate 31 bytes
if (!word[i])
// exit with error
}
Then a read from file can be done like this:
for (i = 0; fgets(line, 40, fr); i++) {
strncpy(word[i], line, maxlength);
printf("word %d: %s\n", i, word[i]);
}
To have one chunk of memory do allocate like this:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int result = EXIT_SUCCESS;
size_t n = 45430;
size_t l = 30;
char (* words)[n][l + 1] = calloc(n, l + 1);
if (NULL == words)
{
result = EXIT_FAILURE;
perror("calloc() failed");
goto lblExit;
}
for (size_t i = 0; i < n; ++i)
{
strncpy((*words)[i], "test", l);
}
for (size_t i = 0; i < n; ++i)
{
printf("%zu: '%s'\n", i, (*words)[i]);
}
free(words);
lblExit:
return result;
}