Segmentation fault when appending char to string in string array - c

So I want to get all the lines from a file and turn them into a char* array. Problem is that whenever I try to append the character onto the end of the element it gives a segmentation fault.
char** loadOutputs(char *fileName, int *lineCount)
{
FILE *file = fopen(fileName, "r");
if (file) {
char c;
int lines = 0;
while ((c = fgetc(file)) != EOF)
if (c = '\n')
lines++;
rewind(file);
char **output = malloc(lines * sizeof(char*));
for (int i = 0; i < lines; i++)
output[i] = "";
int index = 0;
while ((c = fgetc(file)) != EOF)
if (c == '\n')
index++;
else
strcat(output[i], &c);
return output;
}
return NULL;
}
I always get a segmentation fault at strcat(output[i], &c);. I'd rather not create a fixed array size for the output because this could get fairly large and I don't want to use too much memory.

The following code:
for (int i = 0; i < lines; i++)
output[i] = "";
Is setting the pointer to an empty read only string.
You need to allocate some memory for the string:
I.e.
for (int i = 0; i < lines; i++) {
output[i] = malloc(MAX_LINE_LENGTH + 1);
}
Where MAX_LINE_LENGTH is some defined constant - perhaps #define MAX_LINE_LENGTH 100.
You will need to check that when reading the lines you do not exceed this length.
The following code will do this. This will resolve the other problem in that the address of c will not point to a null terminated string.
int index = 0;
int position = 0;
while ((c = fgetc(file)) != EOF) {
if (c == '\n') {
output[index][position] = 0; // Null terminate the line
position = 0; // Restart next line
index++;
} else {
if (position < MAX_LINE_LENGTH) { // Check if we have space!
output[index][position] = c; // Add character and move forward
position++;
}
}
}
output[index][position] = 0; // Add the null to the final line
Also you need to declare c as and int - i.e. change char c to int c. This is because EOF is outside the range for a char

Related

Is there a way to print all string in capital letters without using strupr function as its not a standard library function?

I want to print the data stored in a file which is randomly cased in all caps and strupr() seems to be something that's been listed by someone previously but its not a standard function and may not be cross platform. Is there something which is cross platform?
EDIT 1:
fgets(input1,254,title);
fgets(input2,254,author);
input1[strcspn(input1, "\n")] = '\0';
input2[strcspn(input2, "\n")] = '\0';
printf("<%s> <%s>\n",input1,input2 );
I want to print the string stored in input1 and input2 in uppercase. How to do that?
You can process character by character and use toupper(). Standard function C89 onwards.
Or you can check if character is in between a & z then do a - 32. It will be changed to capital letter.
Here a - 32 = A, because ASCII value of a is 97 and 97 - 32 = 65 and we all know that ASCII value of A is 65.
Code:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *fp;
char buffer[255] = {'\0'}, c;
int i = 0;
fp = fopen("txt.txt", "r");
if(!fp)
{
perror("txt");
exit(1);
}
while( (c = getc(fp)) != EOF)
buffer[i++] = c;
for( i = 0; buffer[i] != '\0'; i++)
{
if(buffer[i] >= 'a' && buffer[i] <= 'z')
buffer[i] = buffer[i] - 32;
printf("%c", buffer[i]);
}
fclose(fp);
return 0;
}
Output:
HELLO!
THIS IS 2ND LINE.
You can use a custom made function, f.e. upcase(). It reads every character in the file, checks whether it is lowercase or not (if it is, the character is adjusted to uppercase using the toupper() function), stores the whole file content into a buffer and then overwrites the file with the content in the buffer:
FILE* upcase (const char* path)
{
int c, cnt = 0, i = 0, j = 1;
int n = 500;
FILE* fp = fopen(path, "r+");
char* buffer = calloc(n, sizeof(char));
if (!fp || !buffer)
{
return NULL;
}
while ((c = fgetc(fp)) != EOF)
{
if ( i == n )
{
j++;
realloc(buffer, sizeof(char) * (n * j));
if (!buffer)
{
return NULL;
}
i = -1;
}
c = toupper(c);
buffer[i] = c;
i++;
cnt++;
}
for ( int i = 0; i < cnt; i++ )
{
if (fputc(c, fp) == EOF)
{
fclose(buffer);
return NULL;
}
}
return fp;
}

Get length of char array with null elements in C

Currently I am making a project that uses char arrays that have null elements. I want to be able to get the length of the array, in the sense of the number of elements that aren't null. This seemed reasonably trivial and I made this function:
int getWordLen(char word[]) {
int count = 0;
for (int i = 0; i < 512; i++) {
if (word[i] != '\0') {
count++;
}
}
printf("%d ", count);
return count;
}
However, every char array returns a length of 188. Any help would be appreciated.
This is the function I was calling it from:
void redact(Words * redactWords, char fileName[]) {
FILE * file = fopen(fileName, "r");
FILE * outputFile = fopen("outputFile.txt", "w+");
char word[512];
int i = 0;
char c;
while (c != EOF) {
c = getc(file);
if ((c > 96) && (c < 123)) {
word[i] = c;
i++;
continue;
}
else if ((c > 64) && (c < 91)) {
word[i] = c + 32;
i++;
continue;
}
i = 0;
if (isWordRedactWord(redactWords, word)) {
//write stars to file
char starStr[512];
for (int i = 0; i < getWordLen(word); i++) {
starStr[i] = '*';
}
fputs(starStr, outputFile);
}
else {
//write word to file
fputs(word, outputFile);
}
strcpy(word, emptyWord(word));
}
fclose(file);
fclose(outputFile);
}
In the initial while, I would only use while(!EOF).
Also, I believe you are using a lot more resources than necessary with the implementation of that for inside the while:
char starStr[512];
for (int i = 0; i < getWordLen(word); i++) {
starStr[i] = '*';
I suggest you to put it outside the while loop and see what happens.
If it is always giving you 188 of lenght, it is counting something that's constant, and may be related to that outer loop.
Hope you can solve it!

Reading strings into 2 dimensional array in C

I want to read a number of strings from a text file (standard input) to a 2 dimensional array using getchar(). please ignore the magic number in the code.
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[]) {
char string[100][20];
int c, j = 0, i = 0;
while ((c = getchar()) != EOF) {
while (c != '\n') {
string[j][i] = c;
i++;
}
string[j][i] = '\0';
j++;
}
printf('string is: %s', string);
return 0;
}
you need to use one more getchar() in inner while loop.
while (c != '\n') {
string[j][i] = c;
i++;
c = getchar(); /* this you need here to fetch char until \n encounters */
}
And need to make variable i again 0 once this string[j][i] = '\0'; is done.
Also this
printf('string is: %s', string);
is wrong. It should be
printf("string is: %s", string); /* use double quotation instead of single */
Sample code
int main(int argc, char *argv[]) {
char string[100][20];
int c, j = 0, i = 0;
while ((c = getchar()) != EOF) { /* this loop you need to terminate by pressing CTRL+D(in linux) & CTRL+Z(in windows) */
while (c != '\n') { /* this loop is for 1D array i.e storing char into each 1D array */
string[j][i] = c;
i++;
c = getchar(); /* add this, so that when you press ENTER, inner while loop fails */
}
string[j][i] = '\0';
j++;
i = 0;/* make it zero again, so that it put char into string[j][0] everytime once 1 line is completed */
}
for(int row = 0;row < j;row++) { /* rotate loop j times since string is
2D array */
printf("string is: %s", string[row]);
}
return 0;
}

Reading a file in C if each row is terminated by a newline

Apparently I'm having some issue reading a file, line by line, or character by character, because each row of my file is terminated by a newline character.
I think the issue is related to those newline characters because when I'm trying to read the file, using or fgetc() or fgets(), when I attempt to print the result on stdout I'm given... nothing.
Example of first file that gives me the issue:
12345678
12849499
47484900
I tried with another file, such as
123456596945869498
And the output on stdout, parsing the file using fgetc() or fgets(), is what I expect: the content of the file.
Now, the aim of the read from file is to store the content of the file in a matrix at pointers. I tried in many ways to bypass those newlines. I tried like this:
i = 0;
while((c = fgetc(f)) != EOF){
if(c != '\n')
p[i][j++] = c; /*Incrementing j by one ad each iteration */
if(c == '\n')
i++; /*If c == '\n', skip to the next row of the matrix */
}
Where I is the row index and j is the column index.
I even tried with fgets, like this, as suggested by a member of this forum:
while((fgets(line, col,f))!= NULL){
p[i++] = strdup(line);
}
Can anybody help me figuring out how to solve this issue?
This is the main of the my program:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define K 100
int main() {
FILE *f;
f = fopen("out_test6_1.txt", "r");
int row = 0;
int col = 0;
char c;
// Evaluating number of rows and columns of the new matrix,
// parsing the file in search of newlines chars
while((c = fgetc(f)) != EOF ) {
if(c != '\n' && row == 0)
col++;
else if(c == '\n')
row++;
}
printf("rows %d\n", row);
printf("columns %d\n", col);
int i, j;
char**p = malloc(row*sizeof(char*));
for(i = 0; i < row; i++) {
p[i] = malloc(col*sizeof(char));
}
i = 0;
while((c = fgetc(f)) != EOF) {
if(c != '\n')
p[i][j++] = c;
if(c == '\n')
i++;
}
for(i = 0; i < row; i++) {
for(j = 0; j < col; j++) {
printf("%c", p[i][j]);
}
}
fclose(f);
return 0;
}
Code reads the file to find the rows and columns yet fails to rewind before the 2nd pass.
i = 0;
rewind(f); // add
while((c = fgetc(f)) != EOF) {
Some other problems noted:
// To properly distinguish all characters from EOF
// char c;
int c;
I'd expect code to find the maximum column width and use that later.
size_t max_col = 0;
while((c = fgetc(f)) != EOF ) {
col++;
if (c == '\n') {
if (col > max_col) {
max_col = col;
col = 0;
}
row++;
}
}
if (col > max_col) {
max_col = col;
}
...
// p[i] = malloc(col*sizeof(char));
p[i] = malloc(sizeof *(p[i]) * max_col);

Why do I get weird number after reading from file?

I get weird values after reading from file (i should be max 100 but I get more), and if someone would explain when to use & * ** in pointers in a simple why couse my english is not very good when it comes to programing I would be grateful
This program should read words from file and if there is a number in the word change it to first letter of that word. If you have any suggestions on how I could change file reading I would also appreciate that. I am new to C (in school I did C++ but very basic levels)
# include <stdio.h>
# define MAX_LEN 100
int File_reading();
int main()
{char buffer;
File_reading();
}
int File_reading( )
{
FILE *stream;
char buffer[MAX_LEN + 1];
int i, ch;
stream = fopen("data.txt","r");
for (i = 0; (i < (MAX_LEN+1));i++)
{
if (((ch = fgetc(stream)) != EOF) && (ch != '\n'))
{
buffer[i] = ch;
}
}
buffer[i] = '\0';
if (fclose(stream))
perror("fclose error");
for (i=0;(i<(MAX_LEN+1));i++){
printf("%c \n", buffer[i]);
}
}
You're not stopping the loop when the file is over, and you're overstepping the array bound! That's terrible. Fix the loop, like this:
char buffer[MAX_LEN + 1];
size_t i;
for (i = 0; i != MAX_LEN; ++i)
{
int c = fgetc(stream);
if (c == EOF) { break; }
buffer[i] = c;
}
buffer[i] = '\0';

Resources