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;
}
Related
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 5 years ago.
Improve this question
I have to use fwrite() instead of fputc(), but I can't understand how it works.
I have tried to use it but it writes in binary. This is the code:
while ((c = fgetc(f1)) != EOF)
{
if (fwrite(&f3, sizeof(f3), 1, f3) == EOF)
{
printf("valore iniziale di errno = %d\n",errno);
perror("errore:");
exit(1);
}
}
f1 is the file where some text is written and f3 is the file where I want to write the content of f1 but I see only binary text.
How fwrite "works"
You can start by looking at the fwrite manual. It's signature is:
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
So, let's break down each argument:
ptr is the source location of your data (where you data is).
size is the size of each element of data. fwrite writes in chunks of size bytes each time it loops.
nmemb is the number of loops fwrite will perform.
stream is the file descriptor (FILE*) of your output file.
So, with that in mind, imagine this:
// our dear string
char *str = "#SO";
// open a bogus file to write
FILE *fp = fopen(foo, "wb");
// call fwrite and store returned value
size_t ret = fwrite(str, 3, 1, fp);
This code will do the following (other than not compiling): Starting at location pointed by str, it will write 3 bytes in the file pointed by fp 1 time. However, if you did it like this:
size_t ret = fwrite(str, 1, 3, fp);
That would tell fwrite to write 1 byte to the file for every iteration it does, and it would do 3 iterations.
In your case, you read a character from f1 and want to write it to f3. Therefore, you should have something like this:
ret = fwrite(&c, sizeof(c), 1, f3);
That will read the binary character from f1 and copy it to f3.
Note that this might not be (and probably is not) the way fwrite works internally. What I presented here is the mental model I use to remember its arguments. If you actually read fwrite source code, you may find a very different implementation.
Example
So, a simple program to copy from f1 to f2 is:
#include <stdio.h>
int main(void)
{
char c;
FILE *f1 = fopen("foo.txt", "rb");
FILE *f2 = fopen("bar.txt", "wb");
size_t ret;
while((ret = fread(&c, sizeof(c), 1, f1)))
ret = fwrite(&c, sizeof(c), 1, f2);
fclose(f1);
fclose(f2);
return 0;
}
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 5 years ago.
Improve this question
This program recieves a pointer to a const char* data type, loads a text file from disk into memory, and passes the address of the first index of the resulting char[] back (essentially passes the contents of the file back as a 'string').
This works just fine, though it sometimes passes back a few extra characters with the file contents.
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
char* loadShaders(char* PATH) {
FILE *fp = fopen(PATH, "rb");
if (fp == NULL) {
perror("[ctb.h] loadShaders() ");
printf("[ctb.h] loadShaders() recieved file path: %s\n", PATH);
exit(-1);
}
fseek(fp, 0, SEEK_END);
long fsize = ftell(fp);
rewind(fp);
char* shader = malloc(fsize + 1);
fread(shader, fsize, 1, fp);
shader[fsize + 1] = '\0';
fclose(fp);
return shader;
}
When it does pass extra characters back, the result looks something like this:
#version 330 core
layout (location = 0) in vec3 aPos;
void main() {
gl_Position = vec4(aPos, 1.0);
}�
As you may have guessed, the "�" does not belong.
Suggestions?
This line causes undefined behavior by writing off the end of an array:
shader[fsize + 1] = '\0';
Simple to fix:
shader[fsize] = '\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 8 years ago.
Improve this question
Could not find proper documentation on this but I am trying to read a file using *nix system call read(). And I want read the file in 1024 byte chunks. Not sure what I have below is correct or not:
while (read(fd, buffer+i, 1024) == 1){
i++;
}
Can someone please verify?
Well if you can't use man, why not just search for it?
Anyway you are using it wrong. If you want to read it by chunks you should do it like this
// consider that we allocated enough memory for buffer
// and buffer is byte array
ssize_t r = 0, i = 0;
do {
r = read( fd, buffer + i, 1024 ); // try to read 1024 bytes
i += r;
} while( r > 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 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){
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';