C programming involving files and structures - c

how to read a negative number from a file using fgetc?

fgetc only reads one character at a time. If you are trying to read in a negative number from a file -- or any number -- use fscanf.
#include <stdio.h>
main()
{
int v;
fscanf (stdin, "%d", &v);
printf ("v = %d\n", v);
}

If the "structures" in the title implies binary, then you likely want to use fread(), but if you really are chasing the question of what the layout of the integer stored in a binary file is, you can use fgetc().
This code shows how to use a union to map a series of read bytes back into an integer.
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
union Integer
{
int intPart_;
char charPart_[4];
};
int main(int argc, char* argv[])
{
FILE* pFile = fopen("integerFile.dat", "w");
int intWritten = -257;
size_t bytesWritten = fwrite(&intWritten, 1, sizeof(int), pFile);
assert(bytesWritten == sizeof(int));
fclose(pFile);
pFile = fopen("integerFile.dat", "r");
int intRead = 0;
size_t bytesRead = fread(&intRead, 1, sizeof(int), pFile);
assert(bytesRead == sizeof(int));
printf("%d\n", intRead);
fclose(pFile);
pFile = fopen("integerFile.dat", "r");
Integer intToRead;
for(int i = 0;
i != sizeof(int);
++i)
{
int byteRead = fgetc(pFile);
intToRead.charPart_[i] = byteRead;
printf("%d\n", byteRead );
}
printf("%d\n", intToRead.intPart_);
fclose(pFile);
return 0;
}

How's the number encoded?
If it's ASCII, remember it takes more than one character. You can write a loop for it, but you might find fscanf more help.
If it's binary data, remember fgetc is only going to read 8 bits anyway -- again, you need to think about other functions to do it efficiently.
The point here really is that unless you're doing it just to prove you can, fgetc is probably the wrong answer. Maybe fgets?

fgetc() interprets the character as an "unsigned char", but casts it to an int (but returns EOF, which is -1, on end of file).
If your source file contains some representation of signed values, then you need to decode that.

'0' has the ascii value 0x30、'1' is 0x31... and so far...
Assuming you have only one number in your file:
FILE * pFile;
int c, n = 0;
bool negative;
pFile=fopen ("myfile.txt","r");
if (pFile==NULL){
perror("Error opening file");
}else{
c = fgetc (pFile);
negative = (c == '-');
do {
c = fgetc (pFile);
if (c>=0x30 && c<=0x39) {
n = n*10 + (c-0x30);
}
} while (c != EOF);
fclose (pFile);
}
if(negative==true) n=n*-1;
printf ("Your number: %d\n",n);

I am with Charlie on the point that there are far better ways to do this than with what would need to be multiple calls to fgetc but if you insist on using that function you would need to run through a loop that evaluates each char. It also does depend on how the data is encoded. If it is ascii (as using a func that returns char would imply) you would check to see if the first char is "-" and then convert each subsequent char to int with atoi(const char*) one at a time, and multiplying your result value by ten each iteration before adding the new value to it. A better way would be to read several chars (using fgets or something) and then convert the char* with atoi(const char*). Maybe if you described more clearly what you were trying to do a better answer could be provided. Beware that using fscanf will fail if your data is not formatted exactly as you specify. But fscanf is really your answer for this problem it seems.

Without over/underflow-check you can use fscanf WITH return-value check:
#include <stdio.h>
int main()
{
int v;
if( 1==fscanf(yourfilepointer, "%d", &v) )
printf ("v = %d\n", v);
else
fputs("error on reading v",stderr);
return 0;
}

Related

Reading integers from txt file in C

I`m making a file reader that reads integers numbers line by line from a file. The problem is that is not working. I think I am using fscanf in a wrong way. Can someone help me?
I had already look for answers in others questions but I can`t find anything that explain why I my code is not working.
int read_from_txt(){
FILE *file;
file = fopen("random_numbers.txt", "r");
//Counting line numbers to allocate exact memory
int i;
unsigned int lines = 0;
unsigned int *num;
char ch;
while(!feof(file)){
ch = fgetc(file);
if (ch == '\n'){
lines++;
}
}
//array size will be lines+1
num = malloc(sizeof(int)*(lines+1));
//storing random_numbers in num vector
for(i=0;i<=lines;i++){
fscanf(file, "%d", &num[i]);
printf("%d", num[i]);
}
fclose(file);
}
The txt file is like:
12
15
32
68
46
...
But the output of this code keeps giving "0000000000000000000..."
You forgot to "rewind" the file:
fseek(file, 0, SEEK_SET);
Your process of reading goes through the file twice - once to count lines, and once more to read the data. You need to go back to the beginning of the file before the second pass.
Note that you can do this in a single pass by using realloc as you go: read numbers in a loop into a temporary int, and for each successful read expand the num array by one by calling realloc. This will expand the buffer as needed, and you would not need to rewind.
Be careful to check the results of realloc before re-assigning to num to avoid memory leaks.
You could try to use the getline function from standard IO and add the parsed numbers into the array using only one loop. See the code below. Please check https://linux.die.net/man/3/getline
Also, you can use the atoi or strtoul functions to convert the read line to an integer. Feel free to check https://linux.die.net/man/3/atoi or https://linux.die.net/man/3/strtoul
The code below evaluate a file with a list of numbers and add those numbers to a C integer pointer
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char ** argv) {
FILE * file;
file = fopen("./file.txt", "r");
size_t read;
char * line = NULL;
size_t line_len = 0;
size_t buffer_size = 10;
int * buffer = (int *)malloc(sizeof(int) * buffer_size);
int seek = 0;
while((read = getline(&line, &line_len, file)) != -1) {
buffer[seek++] = atoi(line);
if (seek % 10 == 0) {
buffer_size += 10;
buffer = (int *)realloc(buffer, sizeof(int) * buffer_size);
}
}
for (int i = 0; i < seek; i++) {
printf("%d\n", buffer[i]);
}
free(buffer);
fclose(file);
}
If you aren't sure which conversion function should you use. You can check the difference between atoi and sscanf at What is the difference between sscanf or atoi to convert a string to an integer?

input from keyboard to a text file in c?? The Code compiles but *EOF* don't works?

#include <stdio.h>
int main ()
{
FILE * pFile;
char ch;
pFile = fopen ("G:\\ IJLAL.txt","w+");
while((ch = getchar())!=EOF)
putc(ch,pFile);
fclose(pFile);
return 0;
}
can you specify the problem???
I am totally new to fopen function.
and please help me with this thing
The getchar() function returns an int value, not a char. By forcing it into a char variable, you are making it impossible to detect the EOF.
Just change char ch to int ch and it will work fine.*
Actually, you will probably still have problems with the file name. Are you sure it should contain a space? And are you aware that \\ is encoded as a single backslash character?
According to the C99 standard (7.19.1.3):
EOF which expands to an integer constant expression, with type int and
a negative value, that is returned by several functions to indicate
end-of-file, that is, no more input from a stream;
The point is that EOF is out of the range of unsigned char. I am sure this was done intentionally so that all 256 basic and extended ASCII characters can still be returned, and are distinct from EOF
You can try this.
1 - Check fopen() return values -> print errno value (perror)
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
int c;
bool run;
FILE *fd;
run = true;
fd = fopen("/tmp/file.txt", "w+");
if (fd == NULL)
{
perror("fopen");
return (1);
}
while (run == true)
{
c = getchar(); // Press ctrl + D for exit
run = (!feof(stdin) && !ferror(stdin));
if (run == true)
putc(c, fd);
}
fclose(fd);
}
And if you want you can see this link.

hexadecimal to decimal conversion

The first piece of code prints each line in b.txt in a new line when it outputs it, and the second code is the conversion from hexadecimal to decimal. I am bad at writing big programs, so I split the task and write smaller programs instead. I am having trouble combining these two programs. Can anyone help ?
#include <stdio.h>
int main ( int argc, char **argv )
{
FILE *fp = fopen ( "b", "r");
char line[1024];
int ch = getc ( fp );
int index = 0;
while ( ch != EOF ) {
if ( ch != '\n'){
line[index++] = ch;
}else {
line[index] = '\0';
index = 0;
printf ( "%d\n", line );
}
ch = getc ( fp );
}
fclose ( fp );
return 0;
}
This is the second program
#include <stdio.h>
#include <stdlib.h>
int main()
{
unsigned int d;
FILE *fp;
FILE *ptr_file;
fp = fopen("normal_data","r"); // read mode
ptr_file =fopen("normal_decimal", "w");
while(fscanf(fp,"%x", &d) == 1)
{
fprintf(ptr_file, "%d /n", d);
}
while( ( d = fgetc(fp) ) != EOF )
fclose(fp);
return 0;
}
It is good programming practice to split your program in small related fragments.
But instead of using a main function everywhere , try making functions which accomplish certain tasks and add them to a header file.
This will make it much easier to write, debug and re-use the code.
In the above case, converting hexadecimal to decimal is clearly something which maybe used again and again.
So, just make a function int hex_to_dec(char* input); which takes a string of input e.g,"3b8c" and converts it to a decimal and returns the converted value.
You may also want to make function void printFile(FILE* fp); which takes the pointer to a file and prints it data to stdout.
You can add these and other functions you have made, to a header file like myFunctions.h and then include the file into whatever program you need to use your functions in.

How to read in a text file of tab-separated integers in C?

I have a file of simply tab-separated integers (a .txt file) and I wish to read them in with just C, line by line. So, say each line has 5 integers. How can I accomplish this?
My first attempt was as follows. It was just to read in a single integer, but even that didn't work:
FILE *fp;
char blah[255];
int *some_int;
fp = fopen("test.txt", "rt");
while (fgets(blah, 255, fp) != NULL)
{
sscanf(blah, "%d", some_int);
printf("%d\n", *some_int);
}
Here's a way no one else suggested, that doesn't use fscanf so you can have sane error handling:
char buffer[BUFSIZE];
size_t size = 5;
int *data = malloc(size * sizeof *line);
if(line == NULL) error();
while(fgets(buffer, sizeof buffer, fp)
{
size_t i = 0;
char *next = buffer;
while(*next && *next != '\n')
{
data[i++] = strtol(next, &next, 0);
// check for errors
}
}
Basically, instead of trying to use *scanf's "%d" to read characters, use the function it (probably) calls to do the conversion: strtol. Where *scanf goes through the string to match the format string but doesn't let you "save your place" in between function calls, strtol does, which is what you need to read an arbitrary number of integers.
I haven't written all your code for you - you have to do the hard error handling. Possible errors include:
i == size, in which case you can try to make data bigger with realloc. Alternately, you could loop through the buffer and count how many numbers there are beforehand, then allocate that many so you don't need to reallocate later.
fgets didn't read the entire line (check that the last character before '\0' is '\n'). In this case you'll probably want to refill the buffer and keep reading numbers. Be careful in this case - you'll likely need to go back and recalculate the last number - fgets might have cut it off. (This is one disadvantage to using fgets.)
Erroneous input - handle however you like.
#include <stdio.h>
int main(){
FILE *fp;
int scanned = 0;
int some_ints[5];
fp = fopen("test.txt", "r");
while ((scanned = fscanf(fp, "%d %d %d %d %d", some_ints, some_ints+1, some_ints+2, some_ints+3, some_ints+4)) != EOF) {
if(scanned ==5){
printf("%d %d %d %d %d\n", some_ints[0], some_ints[1], some_ints[2], some_ints[3], some_ints[4]);
}
else {
printf("Whoops! Input format is incorrect!\n");
break;
}
}
}
I'd do something like this:
int storedVals[MAX_STORED_VALS];
int bf;
int ii=0;
while (!feof(fp) && ii<MAX_STORED_VALS) {
if (fscanf(fp," %d",&bf)) {
storedVals[ii++]=bf;
}
}
fscanf automatically does white space trimming. So as long as there's a space in your scan string, it'll get rid of zero or more \t (tabs) and \n (newlines) to find the next integer. Of course, this doesn't do much by way of error correction.

To generate hexadecimal numbers for 1000 bytes in C

I want to generate hexadecimal numbers in C starting with seed value(initial value) 0706050403020100.My next numbers should be 0f0e0d0c0b0a0908 and so on for next iteration.
In that way i want to generate numbers for say 1000 bytes.
1)how can i generate these hexadecimal numbers.
2)How to store these numbers if i want to compare the generated/produced hexadecimal numbers character by character with the data available in a buffer(dynamic) which has contents of a read file.
Any suggestions/answers are most welcome as i am still learning C language.
EDIT:Here's the code i have tried.
#include<stdio.h>
#include<stdlib.h>
int main(){
FILE *fp;
char *buffer, c;
size_t filesize, result;
int i, expected_data[];
fp = fopen("hex_data", "r");
if (fp == NULL) {
fputs("Error\n", stderr);
exit(1);
}
fseek(fp, 0L, SEEK_END);
filesize = ftell(fp);
printf("Size of hex_data file is:%u \n", filesize);
fseek(fp,0L,SEEK_SET);
buffer = (char*) malloc(sizeof(char)*filesize);
if(buffer == NULL){
fputs("\nMemory error ", stderr);
}
buffer_size = fread(buffer, sizeof(char), size, fp);
for(i=0; i < result; i++) {
printf("%c",*(buffer +i));
}
printf("No of elements read from file are:%u \n", buffer_size);
fseek(fp,0L,SEEK_SET);
int current_pos = 0;
while(current_pos < buffer_size) {
if (buffer[current_pos] != expected_data) {
fputs("Error\n",stderr);
}
else {
current_pos++;
expected_data = next_exp_data(data); //function is call hexadecimal numbers produced
}
}
Here i want to write a function to generate hex numbers for 1000 bytes starting from 0706050403020100.If this is the initial data everytime if i add 08 to each byte i should get the next number(til 1000 bytes).But i don't know how to do it.Can anyone help me out.
Any corrections in the code are most welcome.
This will generate 1000 bytes of random hexadecimal numbers. (Or rather, the ASCII representation of 1000 hexadecimal digits.)
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int i;
for (i=0; i<1000; i++) {
printf("%x", rand()%16);
}
printf("\n");
return EXIT_SUCCESS;
}
If you wanted to store them in a buffer to compare with something else later, you might want to look at sprintf instead of printf. For that, you really need to understand how strings are allocated and used in C first.
EDIT: This might be more what you're after. It reads hexadecimal digits from standard input (which can be redirected from a file if desired) and checks to see if they follow the pattern that you described.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int expected_number = 7;
unsigned int read_number;
while (1 == scanf("%2x", &read_number)) {
if (expected_number != read_number) {
fprintf(stderr, "Expected %02x but got %02x.\n", expected_number, read_number);
}
expected_number--;
if (expected_number == -1) expected_number = 15;
}
return EXIT_SUCCESS;
}
Your numbers are large, so use a 64-bit unsigned integer data type, such as unsigned long long. You won't be able to deal with numbers greater than 2**64 without adopting a new scheme. Print hex values using printf("%x", value).
You can look at GNU GMP library for arbitrarily large integers.

Resources