So, I'm getting a really weird error in my program, and I've narrowed it down to something to do with getline() and declaring an array of size greater than 8. However, I'm super confused as to why it's doing that, so any help or explanation is greatly appreciated.
#include <stdio.h>
#include <stdlib.h>
void populateConfig();
int main(int arc, char *argv[])
{
// when thing is size 8 it works fine
char thing[9];
populateConfig();
return 0;
}
void populateConfig(){
FILE *fp;
char string1[1000], string2[1000];
char *line;
int len = 0;
fp = fopen("ws.conf", "r");
while(fscanf(fp, "%s", string1) != -1){
// Commenting out if statement prevents crash
if(string1[0] == '#'){
getline(&line, &len, fp);
continue;
}
}
fclose(fp);
}
So I'm just reading in a config file, and as shown, when I change the size of thing to 8 or less, it works, and when I comment out the if statement in populateConfig() it also works. Is this something to do with the stack or memory? Should I do something differently?
You need to initialize char *line to NULL first. Then before returning, free it.
https://linux.die.net/man/3/getline
Related
Hi need a little bit of help here. I have a file with 5 lines and I want to put this lines into an array of type char *lines[5]; but I can't figure it out why the following isn't working.
#include <stdio.h>
#include <string.h>
int main(void) {
FILE *fp = fopen("name.txt", "r");
char *str;
char *list[5];
int i = 0;
while (fgets(str, 100, fp) != NULL) // read line of text
{
printf("%s", str);
strcpy(list[i], str);
i++;
}
}
As the commenters stated, you need to create an array (which is nothing more than a space in the memory) of a sufficient size to store your string. One approach to solve your problems is the following, note the comments:
#include <stdio.h>
#include <string.h>
int lines(FILE *file); //try to format the code according to some standard
int main(void) {
FILE *fp = fopen("name.txt", "r");
char list[5][100]; //make sure you allocate enough space for your message
// for loop is more elegant than while loop in this case,
// as you have an index which increases anyway.
// also, you can make sure that files with more than 5 lines
// do not break your program.
for(int i = 0; i<5 ;++i )
{
if(fgets(list[i], 100, fp) == NULL){
break;
}
//list[i] is already a string, you don't need an extra copy
printf("%s", list[i]);
}
}
Edit: as requested I've included the code in 'ledic'. However, it never ran - any of it, not even a hello world printf as first line, so I am relatively sure the problem would never be withinit.
Edit2: ironically enough, it was within the 'ledic' function. Looks like I understand even less about this than I previously thought.
I am writing for my current project at Uni and no one around me can figure out this segmentation fault. It should be pretty straightforward so I appreciate your help.
Code as follows:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void ledic(FILE *fp){
printf("Hello world\n");
int len;
int j, i, k;
char palavra[30];
char dictionary[30][10000][30];
int VecOcorrencias[30];
for (j=0; j<30; j++)
VecOcorrencias[j]=0;
printf("Hello world\n");
while ( fscanf(fp, "%s", palavra) == 1 ) {
len = strlen(palavra);
k = VecOcorrencias[len];
strcpy (dictionary[len][k], palavra);
VecOcorrencias[len]++;
}
for (i=0; i<1000; i++)
printf("%s %d\n", dictionary[5][i], VecOcorrencias[5]);
}
}
FILE *OpenFile( char *nome, char *mode){
FILE *fp;
fp = fopen (nome, mode);
if( fp == NULL){
printf(" Cant open file\n");
exit(1);
}
return (fp);
}
int main( int argc, char *argv[]){
FILE * fp;
fp = OpenFile( argv[1], "r");
ledic(fp);
return(0);
}
The code breaks when it enters the void ledic(FILE *fp) function, and says it cannot access the referenced memory (I suppose *fp).
I cannot for the life of me figure out why. Any thoughts?
The declaration char dictionary[30][10000][30]; creates a 9Mb variable 30*30*1000 = 9'000'000. As it is a local variable it is created on the stack and the default stack size on a typical Linux machine is only 8Mb (on Windows it's even only 1Mb).
If you declare it as static, the variable is not on the stack and therefore it can take more memory than the stacksize.
See this SO article for more details on the static keyword.
I need to write a code that will print the frequency of each word from a given file. Words like "the" and "The" will count as two different words. I've written some code so far but the command prompt stops working when I try to run the program. I just need some guidance and to be pointed in the best direction for this code, or I would like to be told that this code needs to be abandoned. I'm not very good at this so any help would be very appreciated.
#include <stdio.h>
#include <string.h>
#define FILE_NAME "input.txt"
struct word {
char wordy[2000];
int frequency;
} words;
int word_freq(const char *text, struct word words[]);
int main (void)
{
char *text;
FILE *fp = fopen(FILE_NAME, "r");
fread(text, sizeof(text[0]), sizeof(text) / sizeof(text[0]), fp);
struct word words[2000];
int nword;
int i;
nword = word_freq(text, words);
puts("\nWord frequency:");
for(i = 0; i < nword; i++)
printf(" %s: %d\n", words[i].wordy, words[i].frequency);
return 0;
}
int word_freq(const char *text, struct word words[])
{
char punctuation[] =" .,;:!?'\"";
char *tempstr;
char *pword;
int nword;
int i;
nword = 0;
strcpy(tempstr, text);
while (pword != NULL) {
for(i = 0; i < nword; i++) {
if (strcmp(pword, words[i].wordy) == 0)
break;
}
if (i < nword)
words[i].frequency++;
else {
strcpy(words[nword].wordy, pword);
words[nword].frequency= 1;
nword++;
}
pword = strtok(NULL, punctuation);
}
return nword;
}
First off all:
char *text;
FILE *fp = fopen(FILE_NAME, "r");
fread(text, sizeof(text[0]), sizeof(text) / sizeof(text[0]), fp);
Reads probably 4 bytes of your file because sizeof(text[0]) is 1 and sizeof(text) is probably 4 (depending on pointer size). You need to use ftell() or some other means to get the actual size of your data file in order to read it all into memory.
Next, you are storing this information into a pointer that has no memory allocated to it. text needs to be malloc'd or made to hold memory in some way. This is probably what is causing your program to fail to work, just to start.
There are so so SO many further issues that it will take time to explain them:
How you are using strcpy to blow up memory when you place it intotempstr
How even if that weren't the case, it would copy probably the whole file at once, unless the file had NULL terminated strings within, which it may, so perhaps this is ok.
How you compare nwords[i].wordy, even though it is not initialized and therefore garbage.
How, even if your file were read into memory correctly, you look a pword, which is unitialized for your loop counter.
Please, get some help or ask your teacher about this because this code is seriously broken.
I am learning C and I have tried to build a program that outputs its own source. This is my source:
#include <stdio.h>
int S = 512;
int main(){
FILE * fp;
fp = fopen("hello.c","r");
char * line = (char *) malloc(S);
int i = 0;
while (i == 0)
{
i = feof(fp);
printf("%s",line);
fgets(line,S,fp);
}
fclose(fp);
}
I have used the tcc compiler and I got this output:
But notice, I got a hyphen before #include. The rest of the output is correct.
So please can someone explain why I got this hyphen??
You're printing the first line before you've read anything.
#include <stdio.h>
int main(){
FILE *fp = fopen("hello.c", "r");
char line[256];
while (fgets(line, sizeof line, fp) != NULL)
printf("%s",line);
fclose(fp);
return 0;
}
#ooga gave you the correct answer.
The why is that malloc doesn't initialize the memory before it returns it to you, unlike its sister calloc.
Most likely, on another platform / compiler, you'd get something different.
Some compilers use a debug heap that initializes "unitialized" memory to a specific value. The release mode will probably result in random garbage instead of a '-' everytime.
I can't seem to work it out. I am using a .c code that opens a file and reads each line. I would like to save in char*substr 4 characters from the line 9 inside the txt file. The line 5 contains
name=Me She; I would like to have in char*substr just Meli.Need help. THX
Here is the c code:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
FILE *fp;
char str[128];
char str1[128];
if((fp = fopen("/home/folder/file.txt", "r"))==NULL) {
printf("Cannot open file.\n");
exit(1);
}
int lin=0;
while(!feof(fp)) {
if(fgets(str, 126, fp))
printf("%s", str);
if (lin==8)
{
char *c= (char *) malloc(sizeof(char)*strlen(str)+1);
c= strndup(str, strlen(str)-5);?? not working?!!!
printf("d is:",c);
}
lin=lin+1;
}
fclose(fp);
return 0;
}
Your printf is wrong. change it to printf("d is %s\n",c);.
By the way, strdup allocate the memory needed, so you don't have to allocate it yourself. (In fact, you have a memory leak).
You're calling malloc() and then directly overwriting its result with that of calling strndup(), this leaks memory.
Also, the logic in the strndup() call looks wrong. If you want to skip the first 5 characters, you should have str + 5.
If you have strdup(), use:
if (lin==9)
{
char *name = strdup(str + 5);
printf("name is: '%s'\n", name != NULL ? name : "(failed)");
}
Then you should probably break out of the loop. Also note that the pointer name goes out of scope, so it's not available to code outside the loop for instance.