Reading hexadecimal from file - c

I'm trying to read two records form a file, where one is hexadecimal formated number. Well I'm newcomer to C, before when I been reading hexadecimal, generated by ftok(), I just used printf("%x", key) and it worked fine. Now when I try to read it from the file, it does not work that way.
So my code looks like this:
int countRecords(FILE *f_p) {
int tmp_key = 0;
int tmp_msgqid = 0;
int n = 0;
while (!feof(f_p)) {
if (fscanf(f_p, "%x %i", &tmp_key, &tmp_msgqid) != 2)
break;
n = n + 1;
}
return n;
}
Later on i read this value in the code like:
printf("Records: %i \n", countRecords(f_msgList));
And this compiles with no warnings. Anyway when I run the program the value of countRecords(f_msgList) is 0, when the file have a bunch of data in it:
5a0203ff 360448
850203ff 393217
110203ff 425986
EDIT:
Here is the code where the file is opened or created:
FILE *f_msgList;
f_msgList = fopen("../message_queues.list", "a");
// if file does not exist then create one and check for errors
if (f_msgList == NULL) {
FILE *f_tmp;
f_tmp = fopen("../message_queues.list", "w");
if (f_msgList == NULL) {
fprintf(stderr, "Error occurred while creating the file! \n");
exit(1);
} else
f_msgList = f_tmp;
}

Problems
You opened the file in "append" mode. which does not let you read through the file.
If you want to write and then read the file, file pointer must be reset to the starting of the file.
feof(f_p) is worst way of checking whether file pointer is at end of the file.
Solution
Open File in "read" mode by 'r' or in append+read mode 'a+'.
if you are writing in to the file. reset it using rewind(f_p); after writing.
check out this way to read through the file :
int ret, ans, key;
while ((ret = fscanf(fp, "%x %i", &key, &ans))) {
if (ret == EOF)
break;
else
printf("%x %i \n",key, ans);
}
here integer ret is :
EOF, if the pointer is reached end of file.
0, if no input matched with the variable
(greater than 0), that is, number of matched variables with the file input

Related

Writing large quantity of integers in a txt file in c

I wrote this code where I generate random integers in a large quantity and store them in a txt file. it works if I input up to 49 integers
but after that it does not read any further from the file or the file don't accept any further I don't know please help me
this is the code
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *fptr;
int num, n;
fptr = fopen("integers.txt", "w");
if (fptr != NULL)
{
printf("File created successfully!\n");
}
else
{
printf("Failed to create the file.\n");
return -1;
}
printf("Enter some integer numbers [Enter -1 to exit]: ");
scanf("%d", &n);
while (n != 0)
{
num = rand();
putw(num, fptr);
n--;
}
fclose(fptr);
fptr = fopen("integers.txt", "r");
printf("\nNumbers:\n");
int count = 0;
while ((num = getw(fptr)) != EOF)
{
printf("%d\n", num);
count++;
}
printf("\nNumber of elements in the file %d",count);
fclose(fptr);
return 0;
}
You have following problems:
As you're writing binary data, the file needs to be opened with "wb" and "rb" (b stands for binary). Othwerwise certain unwanted text substitutions will take place.
If one of your random numbers turns out to be -1, the read will stop prematurely because EOF has the value -1. Therefore you need to do the end of file check with the feof function instead of comparing the value read with EOF.
fptr = fopen("integers.txt", "wb"); // <<< open with binary mode "wb"
...
fptr = fopen("integers.txt", "rb"); // <<< open with binary mode "rb"
printf("\nNumbers:\n");
int count = 0;
while (1)
{
num = getw(fptr);
if (feof(fptr)) // end of file reached => stop the loop
break;
printf("%d\n", num);
count++;
}
BTW:
The documentation of getw concerning the return value is pretty misleading, especially the part "A return value of EOF indicates either an error or end of file" seems wrong to me. getw can read -1 values (0xffffffff) without problems.

How do I make the file pointer point at the very start of the file?

I'm having trouble setting the file pointer to the very start of a file to write some stuff at first AFTER having already written some text in it.
I've tried rewind(), fseek(), opening the file in "r+" & "a+" modes, nothing seems to work.
Here's a small recreation of the program:
#include<stdio.h>
#include<stdlib.h>
void master_globalprint(int lim)
{
int i = 0;
FILE* maspass;
errno_t err;
err = fopen_s(&maspass, "Master_Password.txt", "r+");
if (err != 0)
{
printf("Error opening Master_Password.txt");
exit(0);
}
rewind(maspass);
printf("Pointing to %ld", ftell(maspass));
while (i < lim)
{
fprintf(maspass, "%d", i); //Writing the array infront of the encrypted code
i++;
}
fclose(maspass);
}
void master_create() //To Create a Master Password
{
int count = 0;
char pass;
FILE* maspass;
errno_t err;
err = fopen_s(&maspass, "Master_Password.txt", "a");
if (err != 0)
{
printf("Error creating Master_Password.txt");
exit(0);
}
printf(" Enter Master Password : ");
while ((pass = getchar()) != EOF && pass != '\n')
{
count++;
fprintf(maspass, "%c", pass); //The characters are then printed one by one
}
if (count == 0)
{
remove("Master_Password.txt");
printf("Master Password cannot be empty");
exit(0);
}
fprintf(maspass, "%c", (count + 33)); //To put the amount of letters into file, forwarded by 33 to reach a certain ASCII threshold and converted to char
fprintf(maspass, "\n");
fclose(maspass);
master_globalprint(count);
}
void main()
{
master_create();
}
The above functions work and print the correct values except the master_globalprint function starts printing exactly where the last function left off.
Is it because I've to use command line arguments to achieve the task? If so, can I set the command line arguments to be executed by default somehow so that if the code is distributed, the user won't have to bother?
EDIT : Added in a reproducible code sample. When I put "a" in line 31, it prints only the stuff I input and not the numbers in master_globalprint(). If I put "w", it ONLY prints the numbers in master_globalprint() and not the stuff I input.
Here the writing mode should be w+:
err = fopen_s(&maspass, "Master_Password.txt", "a" /* w+ */);
Here you should close the file and then remove it:
if (count == 0)
{
/*fclose_s(maspass);*/
remove("Master_Password.txt");
printf("Master Password cannot be empty");
exit(0);
}
Instead of doing this, you should keep the file descriptor open and pass it to master_globalprint:
fclose(maspass);
master_globalprint(count);
/* master_globalprint(count, maspass);
* fclose(maspass); */
Then keep reusing the open file descriptor.

C programming - reading numbers from text file

I'm trying to make a sort of a database program and ran into a few issues with reading integers from a text file in C.
I have the following code:
#include <stdio.h>
int main(){
int index;
FILE * fp;
if((fp = fopen("read_file.txt","r+")) == NULL){
perror("Cannot open file");
printf("\nCreating new file...");
if((fp = fopen("read_file.txt","w+")) == NULL){
perror("\nCannot create file.. Terminating..");
return -1;
}
}
fputs("INDEX = 3",fp);
fscanf(fp, "INDEX = %d",&index);
printf("index = %d\n",index);
fclose(fp);
return 0;
}
When i try to run the program it outputs "index = 16", i tried using fgets and sscanf but same thing happens. With strings however it decides to print out a bunch of characters that don't make sense.
What you see in undefined behavior because you write a string to the file and try to scan INDEX = %d which is not there in the file because of the file pointer is pointing after INDEX = 3
You need to rewind(fp) before scanning.
fputs("INDEX = 3",fp);
rewind(fp);
if( fscanf(fp, "INDEX = %d",&index) != 1)
printf("Scanning failes\n");
else
printf("INDEX = %d\n",index);

How to Read and Write integers to a file

The thing is that im trying to read some integers to know the levels of the game I have already passed through, then I want to put the integer of the current level to one if t is not already. It creates the file but doesn't write anything. Anyone know why? Now, it does it the first time when creating it with printf but when reading it gives status access violation.
void SaveGame(void)
{
FILE *pFile = fopen("SavedData.txt","rb");
int MyArray[8] = {0};
if(pFile)
{
fscanf(pFile, "%d %d %d %d %d %d %d %d" , MyArray[0], MyArray[1], MyArray[2], MyArray[3], MyArray[4], MyArray[5], MyArray[6], MyArray[7]);
fclose(pFile);
}
if(MyArray[Current] == 0)
MyArray[Current] = 1;
pFile = fopen("SavedData.txt", "wb");
if(pFile)
{
fprintf(pFile, "%d %d %d %d %d %d %d %d" , MyArray[0], MyArray[1], MyArray[2], MyArray[3], MyArray[4], MyArray[5], MyArray[6], MyArray[7]);
fclose(pFile);
}
}
You can do what you want something like this (untested) :
#define SAVE_FILE "SavedData.txt"
#define NUMS_SIZE 8
void SaveGame() {
FILE *f;
f = fopen(SAVE_FILE, "r");
if (!f) {
fprintf(stderr, "Error: Can't open save file for reading.\n");
exit(-1);
}
int nums[NUMS_SIZE] = {0};
int n, i = 0;
while (fscanf(f, "%d", &n) == 1) {
if (i >= NUMS_SIZE) break;
nums[i++] = n;
}
fclose(f);
f = fopen(SAVE_FILE, "w");
if (!f) {
fprintf(stderr, "Error: Can't open save file for writing.\n");
exit(-1);
}
int j = 0;
if (i > 0) fprintf("%d", nums[0]);
for (j = 1; j < i; ++j)
fprintf(" %d", nums[j]);
fclose(f);
}
That's not how you read a file.
For starters if it is a text file, open with mode "r", not "rb".
When you do a read operation you should check to see whether the read operation suceeded or failed. You don't do feof instead. There is a lot of code out there that does feof and most of it is wrong. Be wary when copying off internet code samples.
Also, it's a great idea to read the documentation for any standard function you use. You may learn things about the function that you didn't know. For example, fscanf returns how many items were successfully read.
So in your reading loop, either check that fscanf returns 8 (or loop 8 times as ooga suggested, checking for 1 each time). Don't check feof during the loop.
Once the read fails, THEN you have the option to do feof to find out why the read failed, if you care to know. It could have fail because you hit the end of file (feof), or because of a device error (ferror), or because the file had words in it instead of numbers.
When you do the writing part, make sure you only write numbers which were successfully read.

C: I/O - Quickest /best way to read ints from file

Trying to work with C I/O currently. I have a file that only holds integers and there is only one per line.. not commas, etc.. what is the best way to read them in:
//WHILE NOT EOF
// Read a number
// Add to collection
I am creating 2 files which is working fine.. but ultimately, I want to read them both in, join them into one collection, sort them and then print them out to a new file. There's no need for you to do all that for me, but please help with the above.. here is my effort so far:
void simpleCopyInputToOutput(void);
void getSortSave(void);
int main()
{
//simpleCopyInputToOutput();
getSortSave();
system("PAUSE");
return 0;
}
void getSortSave(void)
{
FILE *fp1;
FILE *fp2;
FILE *fpMerged;
printf("Welcome. You need to input 2 sets of numbers.\n");
printf("Please input the first sequence. Press 0 to stop.\n");
if ((fp1 = fopen("C:\\seq1.txt", "w")) == NULL)
{
printf("Cannot open or create first file!\n");
exit(1);
}
int num;
int i = 1;
while (num != 0)
{
printf("Please input value # %d\n", i);
scanf("%d", &num);
if (num == 0)
{
break;
}
fprintf(fp1, "%d\n", num);
i++;
}
printf("Please input the second sequence. Press 0 to stop.\n");
if ((fp2 = fopen("C:\\seq2.txt", "w")) == NULL)
{
printf("Cannot open or create second file!\n");
exit(1);
}
num = -1;
i = 1;
while (num != 0)
{
printf("Please input value # %d\n", i);
scanf("%d", &num);
if (num == 0)
{
break;
}
fprintf(fp2, "%d\n", num);
i++;
}
fclose(fp1);
fclose(fp2);
if ((fp1 = fopen("C:\\seq1.txt", "r")) == NULL)
{
printf("Cannot open first file!\n");
exit(1);
}
//WHILE NOT EOF
// Read a number
// Add to collection
//TODO: merge ints from both files, sort and output to new file
}
I would suggest you use fgets:
char buffer[16];
while (fgets(buffer, sizeof(buffer), fp1))
{
long value = strtol(buffer, NULL, 10);
/* Use the value... */
}
/* fgets failed ro read, check why */
if (!feof(fp1))
printf("Error: %s\n", strerror(errno));
Edit: How to get the number of entries in the file: If you don't keep track of it any other way (like e.g. having the number of items being the first line), the only solution may be to read the file twice. Once to count the number of lines, and once to read the actual numbers. Use fseek or rewind after the counting to "rewind" the read pointer to the beginning of the file.
I would personally put the counting in a separate function, and also the actual reading. This way you don't have to duplicate code if you want to read from multiple files.
Your problem can be divided into three different parts: reading in two files, sorting the data, and writing the output into a file. I am assuming here that the two input files are not already sorted. If they were, the problem would be greatly simplified (google for mergesort if that is the case).
If you want to open a file for reading, you have to use "r" instead of "w" as file open mode flag. In your example code the read/write parts are somehow reversed from what you describe above. Then you should use fscanf to read formatted input from a FILE*. scanf(...) is just short for fscanf(stdin, ...). You can access the files in the following way:
FILE *fin1 = fopen("seq1.txt", "r");
FILE *fin2 = fopen("seq2.txt", "r");
FILE *fout = fopen("out.txt", "w");
if (fin1 && fin2 && fout) {
// Do whatever needs to be done with the files.
}
if (fout)
fclose(fout);
if (fin2)
fclose(fin2);
if (fin1)
fclose(fin1);
Using dynamic memory to store the integers is difficult. You need to use realloc to grow a buffer as you write more and more data into it, and finally use qsort to sort the data. Someone else can hopefully give more insight into that if needed.

Resources