Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a HTML file that I've retrieved through curl and I wanted to find certain strings in the file so that I could analyse whether I have received the response I expected.
Here's the function I'm using to search for my string:
int find_str(FILE *infile, char *str)
{
char tmp[512];
while(fgets(tmp, sizeof(tmp), infile) != NULL)
{
if (strstr(tmp, str) != NULL)
{
printf("found %s in file\n", str);
return 1;
}
}
fprintf(stderr, "Couldn't Find %s in file!\n", str);
return 0;
}
and it's called as follows:
if(find_str(html_file, "<h1>Hello World</h1>") == 1)
{ ... }
First, the string is never found even when it is present. Second, this function is called in another if statement if the first should fail, but while watching execution in the debugger, it completely skips the while loop. No garbage values are given. If I watch the tmp array, the values seem normal, although they seem to have been encoded.
With that function, if your search string sits around 512 byte boundaries in the file, it won't match because you only check inside 512 byte blocks.
To fix this issue, you can load the whole file into memory instead. This also has an advantage on performance if you decide to search multiple times, as you won't have to do I/O every time.
This should work to read a file into memory:
fseek (infile, 0 , SEEK_END);
int filesize = ftell (infile);
rewind (infile);
char *whole_file = malloc(filesize+1);
if (!(filesize == fread(whole_file, filesize, 1, infile))) {
// ERROR
}
whole_file[filesize] = '\0';
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I am writing a program that reads a string and writes that string in another file which has not been created.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
char s[50];
FILE *fp;
fp = fopen("E:\\poem.txt","w");
if(fp = NULL)
{
printf("Cannot open file");
exit(1);
}
printf("Enter a string\n");
while(strlen(gets(s))>0)
{
fputs(s,fp);
fputs("\n",fp);
}
fclose(fp);
return 0;
}
Since the "w" mode creates a new file if file is not already created,my program creates that file however it is unable to write it to the file
The double slash in fp = fopen("E:\\poem.txt","w"); is because i thought \p cannot be a escape sequence but i want to go to the directory E:\ so i used double slash.
However I even tried fp = fopen("poem.txt","w"); same thing happen creates a file but doesnot write on it.
Also checked this question but was not helpful C: can't write data on file
From man page of gets():
gets() returns s on success, and NULL on error or when end of file
occurs while no characters have been read.
When gets() return NULL (on failure), then strlen(NULL) causes segmentation fault.
So, you can simply use while(gets(s)!=NULL) instead of while(strlen(gets(s)) > 0)
As you mentioned in comment a typo use== instead of =
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char s[50];
FILE *fp;
fp = fopen("E:\\poem.txt", "w");
if (fp == NULL)
{
printf("Cannot open file");
exit(1);
}
printf("Enter a string\n");
while (strlen(gets(s)) > 0)
{
fputs(s, fp);
fputs("\n", fp);
}
fclose(fp);
return 0;
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I would like to merge two files using open and file descriptor. Moreover I would like to separate the content of the first file with - before writing the the content of the second file.
I did the following :
void merge (char* fileName, char *fileName1) {
int fd = open(fileName, O_RDWR);
char c;
while (read(fd, c, 1) > 0) {//going at the end of the first file
}
char next[] = "\n";
char charc[] = "-";
write (fd, next, strlen(next));
for (int i = 0; i < 80; i++) {
if (write (fd, charc, strlen(charc)) == -1) {
perror("error : ");
}
}
write (fd, next, strlen(next));
int fd1 = open(fileName1, O_RDWR);
while(read(fd1, &c, 1) > 0) {
write(fd, &c, sizeof(c));
}
close(fd1);
close(fd);
}
Is there a better way to write this code ? Moreover I have a little problem even if it works it seems like I don't have the right to read the new file. For example if I do cat newFile I have a permission denied.
Is there a better way to write this code ?
You are not handling errors of all calls. All of syscalls open, write, read and close return -1 on error and set errno and may do that at any time. EINTR could be handled.
going at the end of the first file open has O_APPEND flag mode that is used for appending data.
Copying one character at a time is very not optimal. With glibc standard library you could use BUFSIZ bytes at a time that is chosen for fast I/O output. You could make a copy of a big chunk size at a time that is a power of 2, like 2048 or 4096.
There is little reason to use file descriptors here - prefer to use standard FILE * handling, which would make your code portable and also buffer the data for faster I/O.
If you wish to create the file use O_CREAT and add the third argument to open that is the mask of permissions of new file.
On linux there is splice(2) system call that can be used to append data on kernel side for maximum efficiency.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 5 years ago.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
I have designed a program in c program to count the number of rows but it shows the garbage values.
My file contains the data as follows
2,8,10
3,5,7
4,5,1
3,6,8
3,7,8
3,8,4
for counting the number of rows i have written the program as
int count_lines =0;
char sample_char;
FILE *fptr;
fptr = fopen("demo3.txt", "r");
sample_chr = getc(fptr);
while (sample_chr != EOF)
{
if (sample_chr == '\n')
count_lines = count_lines +1;
sample_chr = getc(fptr);
}
printf("\n\n\n The number of lines are %d",count_lines);
but the garbage values are being printed here. Where i am going wrong???
when i am writing the below code it works perfectly
typedef struct ratings {
int userId;
int movieId;
int rating;
}Ratings;
int i, n=65;
FILE *fptr;
fptr = fopen("demo3.txt", "r");
/* *//counting the number of lines present in the above file
sample_chr = getc(fptr);
while (sample_chr != EOF)
{
if (sample_chr == '\n')
count_lines = count_lines +1;
sample_chr = getc(fptr);
}* */
printf("\n\n\n The number of lines are %d",count_lines);
//storing the values in array of structures
for(i=0;i<n;i++)
fscanf(fptr, "%d,%d,%d", &REC1[i].userId, &REC1[i].movieId, &REC1[i].rating);
now if i am printing the contents i am getting the output. If i remove the comment lines then garbage value appears
You forgot to check whether the file opened.
fptr = fopen("demo3.txt", "r");
Every file operation, especially opening a file, should be error checked. Here's an example.
#include <stdio.h>
#include <string.h>
#inculde <errno.h>
...
char filename[] = "demo3.txt";
FILE *fptr = fopen(filename, "r");
if( fptr == NULL ) {
fprintf( stderr, "Could not open %s for reading: %s\n",
filename, strerror(errno)
);
exit(1);
}
//storing the values in array of structures
for(i=0;i<n;i++)
fscanf(fptr, "%d,%d,%d", &REC1[i].userId, &REC1[i].movieId, &REC1[i].rating);
This would be what is producing the garbage. Because it comes after getc is done reading the file, calls to fscanf will try to read past the end of the file and fail (again, check every file operation). Nothing will be put into REC1, it will contain the garbage it had when it was declared.
Think of fptr like a cursor in an editor. Every time you read from it, the cursor moves forward. Every call to getc moves the cursor forward one character. By the time you call fscanf, it's reached the end of the file.
You can move the cursor around with fseek. Use it to move fptr back to the beginning of the file. And, yup, check to make sure it worked.
if( fseek(fptr, 0, SEEK_SET) != 0 ) {
fprintf( stderr, "Could not rewind %s: %s\n", filename, strerror(errno) );
}
Note that you'll still get garbage because you're reading n times rather than count_lines times.
Note that you can't display the offending line. This, and many other reasons, is why it's best to avoid fscanf and instead read the line with fgets and use sscanf to parse the line. This also does away with the need to read n times, just read until all the lines are done.
// A line buffer
char line[1024];
int i = 0;
// Read a line
while( fgets( line, sizeof(line), fptr) != NULL ) {
// Parse the line
if( sscanf(line, "%d,%d,%d", &REC1[i].userId, &REC1[i].movieId, &REC1[i].rating) < 3 ) {
fprintf( stderr, "Could not understand '%s' from %s\n", line, filename );
continue;
}
// Print what we got
printf("uid: %d, mid: %d, rating: %d\n", REC1[i].userId, REC1[i].movieId, REC1[i].rating);
i++;
}
As for making sure REC1 is big enough to hold all the lines, look into realloc.
after walking through the file, counting the number of lines,
Then need to rewind() or lseek() the file back to the beginning before extracting the data
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I'm writing a C code and, for some reason, the code I'm writing just needs to read without actually writing to a memory buffer. I can conveniently write data to a dummy local variable, but there must be unnecessary overheads caused by writing some variables to memory.
int rdsize = 0;
while (rdsize > SOME_BYTES) {
rdsize += fread (/* SOME BUFFER */, 1, SOME_BYTES - rdsize, file);
if (rdsize == -1) break;
}
In a word, I'd like to make the above code work without /* SOME BUFFER */. How can I do this? Close solutions are also greatly welcomed.
You can use fseek to skip an arbitrary number of bytes:
#include<stdio.h>
// Inside a function:
success = fseek(file, 1, SOME_BYTES - rdsize, SEEK_CUR);
if the purpose of your function is just to know the size of the file then you can use this function:
int filesize(FILE *file ){
int pos, size = -1;
pos = fseek( file, 0, SEEK_CUR); //save current position
if( pos != -1 ){
fseek(file, 0 , SEEK_END); // move to end
size = ftell(file); // get file size
fseek(file, pos, SEEK_SET); // rewind
}
return size;
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I want to open file in 20 loop. Every time the name of the folder changes.Like This variables1,variables2,variables3......variables20 I found the same question in here , but it didnt help me.
Here's what I have tried:
int l=1;
while(l<20){
char filename[10];
sprintf (filename, "variables%d", l);
OR
scanf("%s", filename);
FILE * fp;
if ((fp = fopen (filename,"rb")) == NULL){
printf("Failed to Open File variables%d\n",l);}
........... Reading Data........
fclose (fp);
l++;
}
I can wite Filename succesfully but I got the error: Failed to Open File variables1
[SOLVED] I am just sodding idiot.Thank you for your concern and answers... i just forgot to add ".bin" sprintf (filename, "variables%d.bin", l);
You never increment your counter.
I would also recommend you to use a for loop like this
for(int i = 1; i < 20; i++){
// Your code
}
Your filename buffer is too short - "variables1" requires 10 characters plus a '\0' terminator, so you need at least 11 characters for this buffer, and more when the index is > 9, otherwise you will get a buffer overflow and undefined behaviour. Change:
char filename[10];
to:
char filename[PATH_MAX]; // PATH_MAX is defined in <limits.h>
Also: if, as your title suggests, you want to write to these files, then you need to change:
if ((fp = fopen (filename,"rb")) == NULL){
to:
if ((fp = fopen (filename,"wb")) == NULL){