Loading a file from disk, loads a few extra characters [closed] - c

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';

Related

errors when writing to a bin file [closed]

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 1 year ago.
Improve this question
struct Seats seats[12];
FILE* inp;
FILE* opt;
int counter = 1;
char option;
if ((inp = fopen("seats.bin", "rb")) == NULL) {// open file to read
printf("file did not open!");
exit(0);
}
fread(&seats, sizeof(struct Seats), 12, inp);// save file data to struct array
//later in the code
opt = fopen("seats.bin", "w");
fwrite(seats, sizeof(struct Seats), 12, opt);
fclose(inp);
i have no problems reading the data from the bin file. however when i try to write to the file it stores random values making it imposable to read when i boot up the program again.
if you guys know the problem i would appreciate the help
If you're on windows, it's important to write wb instead of only w on this line opt = fopen("seats.bin", "wb"); to refer to a binary file:
struct Seats seats[12];
FILE* inp;
FILE* opt;
int counter = 1;
char option;
if ((inp = fopen("seats.bin", "rb")) == NULL) {// open file to read
printf("file did not open!");
exit(0);
}
fread(&seats, sizeof(struct Seats), 12, inp);// save file data to struct array
//later in the code
opt = fopen("seats.bin", "wb");//w for write, b for binary
fwrite(seats, sizeof(struct Seats), 12, opt);
fclose(inp);
You need to check how many you actually read and only write that many. Otherwise if you read fewer than you expect you'll write out whatever garbage was in seats.
size_t num_read = fread(seats, sizeof(struct Seats), 12, inp);
// later
fwrite(seats, sizeof(struct Seats), num_read, opt);
Also...
Check fopen worked.
Use wb for writing binary, like rb. It's only important on Windows machines.

Writing to a file. Creates file but does not write in it [closed]

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;
}

Copying file text in C using getc() and putc() - binary code in the output file [closed]

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
I created a file called "text.txt" with a string inside and I want to copy that string in another file called "copiaqui.txt". But there's a problem. In the output file, I found this :
Why the program doesn't copy the string correctly?
Code :
#include <stdio.h>
#include <stdlib.h>
void copiaFile(FILE *fi, FILE *fo);
int main(void)
{
FILE *fi = fopen("test.txt", "r");
FILE *fo = fopen("copiaqui.txt","w");
if (fi == NULL)
{
printf("\nImpossibile aprire il file test.txt\n");
exit(EXIT_FAILURE);
}
if (fo == NULL)
{
printf("\nImpossibile aprire il file copiaqui.txt\n");
exit(EXIT_FAILURE);
}
copiaFile(fi, fo);
fclose(fi);
fclose(fo);
return 0;
}
void copiaFile(FILE *fi, FILE *fo)
{
int var;
while((var = getc(fi) != EOF))
{
printf("\nCarattere acquisisto : %c", var);
putc(var, fo);
}
}
You have made a common mistake with this expression:
var = getc(fi) != EOF
What this does is assign the value of (getc(fi) != EOF) to var, because of something called operator precedence. The value is either true or false. What you intended to do is:
(var = getc(fi)) != EOF
Which will make var have the getc() value, then check that against EOF.

Reading file data without writing it to memory [closed]

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;
}

Why is writing to existing files slower than writing to nonexisting files? [closed]

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 8 years ago.
Improve this question
Consider the following example code:
/* verify.c */
#include <stdio.h>
int
main (int argc, char *argv[])
{
if (argc < 2)
return 0;
char *filename = argv[1];
FILE *f = fopen(filename, "w");
if (!f)
perror("something went wrong");
// random data
#define SIZE 65536
#define ITER 1024
unsigned int buffer[SIZE] = { 0 };
unsigned int i;
for (i = 0; i < ITER; ++i)
{
int res = fwrite(buffer, sizeof(*buffer), SIZE, f);
if (res != SIZE)
perror("something went wrong");
}
fclose(f);
return 0;
}
Uninterestingly, his program will write random data to a file.
Interestingly though, the program is orders of magnitude faster, if the file does not exist, although its contents are not at all relevant to the program.
time ./verify notexists
real 0m0.162s
user 0m0.000s
sys 0m0.162s
time ./verify exists
real 0m3.807s
user 0m0.002s
sys 0m0.268s
Why is that?
EDIT:
thanks to #rodrigo's suggestion below, I ran both cases throuh strace, and it reported that the close system call takes a long time to complete if the file exists.
if the file exists:
close(3) = 0 <2.673454>
otherwise:
close(3) = 0 <0.000011>
When the file does exist, "w" will truncate it, that is, remove all its contents. That takes time, possibly a lot of time is the file is very big and the file system is not very good (FAT?).
Opposed to that, when the file does not exist, it will be created, that is to add a directory entry and an inode or whatever the file system uses. But these structures are always small, so it is not a big deal.

Resources