I am trying to take 500 numbers in this text file and store them into an array, it keeps giving me random numbers that aren't in my text file at all. I've also changed a few things and it is saying that there is conflicting types for my fp_read
#include<stdio.h>
int ch;
int X[500];
FILE*fp_read = NULL;
fp_read = fopen("random_numbers.txt","r");
int main()
{
for(i=0;i<499;i++)
{
if(ch==EOF)
{
printf("End of File\n");
}
else
{
ch = (fgetc(fp));
X[i]=ch;
printf("%d,"X[i]);
}
}
return 0;
}
sorry for the quick answer but try to use atoi or strtol to convert the character to integer or add -48 because '0' in ascii is 48
You are interpreting the character codes of the digits used to encode the textual numbers, which is probably not at all what you want. For instance in UTF-8 the number "12" consists of the two code points 1 and 2, which encode as the two 8-bit values 49 and 50.
For line-based input, it's almost always best to read whole lines into a suitably large buffer, then parse that. That is more robust than parsing the stream itself.
Something like:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE * const fp = fopen("random-numbers.txt", "rt");
if(fp == NULL)
{
fprintf(stderr, "**File open failed\n");
exit(1);
}
int numbers[500];
int index = 0;
char line[1024];
while(fgets(line, sizeof line, fp) != NULL)
{
if(index >= sizeof numbers / sizeof *numbers)
break;
numbers[index++] = (int) strtol(line, NULL, 10);
}
printf("Read these numbers:\n");
for (int i = 0; i < index; ++i)
printf("%d: %d\n", i, numbers[i]);
return 0;
}
Related
Write code that reads a number of values, interpreted as integers, from a file named “mtData.txt”, where the first number tells how many subsequent numbers there are, and there will never be more than 100 integers.
I'm new to C, coming from a background in Java. I wrote the following, producing an infinite loop that prints the obvious statements and an address not the values from the file.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main(){
FILE *fp = (FILE*) 0;
int c = -1;
fp = fopen("myInput.txt", "r");
if(fp == NULL){
puts("Error accessing file");
return(-1);
}
bool doneReading = false;
int numbers[100];
while (!doneReading){
puts("Reading now");
c = fscanf(fp, "%d", numbers);
printf("Read %d items\n", c);
if(feof(fp)){
doneReading = true;
}
printf("%d\n", numbers);
fclose(fp);
}
}
A possible approach (take a look at how the loop is implemented):
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main(void) {
FILE* fp = fopen("myInput.txt", "r");
if (fp == NULL) {
puts("Error accessing file");
return 1;
}
// this is the array that will contain the numbers
int numbers[100];
// this is the number of integers that the file contains
int max_numbers;
// this is the number of integers that we have actually read from the file
int counter = 0;
// max_numbers is actually the first integer that we find in the file
if (fscanf(fp, "%d", &max_numbers) != 1 || max_numbers < 0 || max_numbers > 100) {
printf("ERROR\n");
return 1;
}
printf("Max numbers: %d\n", max_numbers);
// now that we know the number of integers, we can loop to read them all
while (counter < max_numbers) {
if (fscanf(fp, "%d", &numbers[counter]) != 1) {
printf("ERROR\n");
return 1;
}
counter += 1;
}
// now we print all the numbers that we have read
for (int i = 0; i < counter; i += 1) {
printf("Number #%d = %d\n", i, numbers[i]);
}
fclose(fp);
return 0;
}
I used fscanf(fp, "%d", &var) != 1 to put the number inside var and check that everything went well (fscanf() will return the number of arguments successfully assigned, in this case only %d).
EDIT:
The previous code does not check if the file contains more data than necessary (that would also mean that the file is not valid), so it just ignores that extra data (thanks #chux for pointing it out).
Also note that fscanf() will not detect integer overflows, so in the future you may want to look at alternative approaches for integer parsing (e.g.: strtol()).
Hi guys i wanna read a text file word by word and count the words while doing it and then pass the words and numbers to my linked list.
But i have a loop problem. I can't escape from the infinite loop.
Here is my code:
int main()
{
char kelime[100];
char kelime2[100];
long a = 0;
FILE * dosya = fopen("oku.txt", "r");
while(1)
{
fseek(dosya,a,SEEK_CUR);
if(feof(dosya))
{
break;
}
while(fscanf(dosya, "%99[^ \n]", kelime) == 1)
{
printf("%s \n",kelime);
a = ftell(dosya);
}
while(1)
{
fscanf(dosya, "%s" , kelime2);
printf("%s \n",kelime2);
if((strcmp(kelime, kelime2))== 0)
{
// Things to do...
}
memset(kelime2,0,sizeof(kelime2));
if(feof(dosya))
{
rewind(dosya);
break;
}
}
}
fclose(dosya);
return 0;
}
To read any kind of space-delimited word, all you need is something like:
while (fscanf(dosya, "%99s", kelime) == 1)
{
// Do something with the "word" in kelime
}
The scanf family of functions all return the number of conversions it successfully made. With a single conversion specifier it can only return 1 on success, 0 if the specifier could not be matched (should never happen in this case) or -1 on error or end of file.
The loop will simply read all words in the input file until the end of the file.
Putting it together in a program that reads and print all words, it would look something like this:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *dosya = fopen("oku.txt", "r");
if (dosya == NULL)
{
perror("Could not open file");
return EXIT_FAILURE;
}
char kelime[100];
size_t counter = 0;
while (fscanf(dosya, "%99s", kelime) == 1)
{
printf("Read word #%zu: %s\n", ++counter, kelime);
}
fclose(dosya);
printf("There was a total of %zu \"words\" in the file\n", counter);
}
A little explanation for the %zu format specifier for printf:
The u is the base format (it's really %u), and stands for unsigned integer. The z prefix tells printf that the corresponding argument is really a size_t value.
The type size_t is a standard C type that is used for all kinds of sizes, counters and indexes. It's an unsigned integer of unspecified size.
I'm trying to read from a text file in C that contains a list of 8 bit binary numbers to be used in another function.
The text file is formatted like:
01101101
10110110
10101101
01001111
11010010
00010111
00101011
Ect. . .
Heres kinda what i was trying to do
Pseudo code
void bincalc(char 8_bit_num){
//does stuff
}
int main()
{
FILE* f = fopen("test.txt", "r");
int n = 0, i = 0;
while( fscanf(f, "%d ", &n) > 0 ) // parse %d followed by a new line or space
{
bincalc(n);
}
fclose(f);
}
I think i'm on the right track, however any help is appreciated.
This is not the standard track to do it, but it ok. You are scanning the file reading ints so it will read the string and interpret them as decimal number, which you should in turn convert to the corresponding binary, i.e. converting 1010 decimal to 2^3+2^1=9 decimal. This is of course possible, you just need to transform powers of ten to powers of 2 (1.10^3+0.10^2+1.10^1+0.10^0 to 1.2^3+0.2^2+1.2^1+0.2^0). Be careful that this work with 8-bits numbers, but not with too huge ones (16-bits will not).
The more common way is to read the strings and decode the strings directly, or read char by char and make an incremental conversion.
If you want to have a number at the end, I would suggest something like the following:
int i;
char buf[10], val;
FILE* f = fopen("test.txt", "r");
while( ! feof(f) ) {
val = 0;
fscanf(f, "%s", buf);
for( i=0; i<8; i++ )
val = (val << 1) | (buf[i]-48);
/* val is a 8 bit number now representing the binary digits */
bincalc(val);
}
fclose(f);
This is just a short snippet to illustrate the idea and does not catch all corner cases regarding the file or buffer handling. I hope it will help anyway.
I think this is a possible solution, i made it simple so you can understand and adapt to your needs. You only need to repeat this for each line.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *file =fopen("data","r");
char *result=calloc(1,sizeof(char));
char line[8];
int i=0;
for(;i<8;i++)
{
char get = (char)getc(file);
if(get == '0')
*result <<= 1;
else if(get == '1')
*result = ((*result<<1)|0x1) ;
}
printf("->%c\n",*result);
return 0;
}
I don't know of a way to specify binary format for fscanf() but you can convert a binary string like this.
#include <stdio.h>
#include <stdlib.h>
void fatal(char *msg) {
printf("%s\n", msg);
exit (1);
}
unsigned binstr2int(char *str) {
int i = 0;
while (*str != '\0' && *str != '\n') { // string term or newline?
if (*str != '0' && *str != '1') // binary digit?
fatal ("Not a binary digit\n");
i = i * 2 + (*str++ & 1);
}
return i;
}
int main(void) {
unsigned x;
char inp[100];
FILE *fp;
if ((fp = fopen("test.txt", "r")) == NULL)
fatal("Unable to open file");
while (fgets(inp, 99, fp) != NULL) {
x = binstr2int(inp);
printf ("%X\n", x);
}
fclose (fp);
return 0;
}
File input
01101101
10110110
10101101
01001111
11010010
00010111
00101011
Program output
6D
B6
AD
4F
D2
17
2B
Read the file line by line, then use strtol() with base 2.
Or, if the file is guaranteed to be not long, you could also read the full contents in (dynamically allocated) memory and use the endptr parameter.
I have a hashtable ADT which has two functions, insert and lookup. I put in to the insert function a hash table, hash table size, ID #, and book title and that inserts it into the hash table. This works fine when I pass it a string literal, i.e. insert(...,"Hello, world!"...); It doesn't work when I read in strings from a file, store them in an array, and try and use my insert and lookup functions.
I have all of my code here but the most important files are main.c and hash.c. Hash.c has the newHash(), hash(), insert(), and lookup() functions and main.c reads from two files, in this case test1.lib.in and test1.req.in, and from the first file will get the library id and title of a book from each line and then put it in the hash table. From the second file, it gets requests for a book title and should print the ids in its linked list.
List of links to files https://docs.google.com/document/d/1tFNs-eVkfnCfjwAHcAUdHtUl1KVv_WcnW2IS0SRFvcM/edit?usp=sharing
Example of code that works.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "list.h"
#include "hash.h"
int main(){
ListHndl* temp = newHash(10);
insert(442440, "cvyaqbznxel", 10,temp);
lookup(temp,"cvyaqbznxel", 10);
return 0;
}
Code that doesn't work
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include "list.h"
#include "hash.h"
int main(int argc, char * argv[]) {
if (argc != 3) {
printf("Incorrect arguments, please specify 2 files to be read\n");
return EXIT_FAILURE;
}
FILE *file = fopen( argv[1], "r");
FILE *secondFile = fopen(argv[2], "r");
if (file == 0 || secondFile == 0) {
printf("Could not open a file\n");
return EXIT_FAILURE;
}
int numDataLines2;
int numDataLines;
int hashTableSize;
//First line of first file gives number of lines in file and
//size of hash table to be made
if(fscanf(file, "%d%d", &numDataLines, &hashTableSize) < 2) {
printf("Unable to parse first line of first file\n");
return EXIT_FAILURE;
}
ListHndl* theHash = newHash(hashTableSize);
int libraryID;
char *tempString = calloc(numDataLines,41*sizeof(char));
char lineHolder[129];
//discard the new line which always shows up
fgets(lineHolder, 128, file);
for(int i = 0; i < numDataLines; i++) {
//Gets the whole line to be scanned with sscanf
fgets(lineHolder, 128, file);
//If the line consists of just a newline char, continue
if(strcmp(lineHolder, "\n") == 0 ) {
continue;
}
//Scans the line retrieved from fgets and placed in lineHolder
if(sscanf(lineHolder, "%d, %40[^\n]", &libraryID,&tempString[i]) == 0){
printf("Unable to parse line %d of first file\n",i+2);
return EXIT_FAILURE;
}
insert(libraryID, &tempString[i], hashTableSize, theHash);
}
char String[41];
fgets(String, 40, secondFile);
numDataLines2 = atoi(String);
char *storeSecondFileStuff = calloc(numDataLines2,41*sizeof(char));
for(int i = 0; i< numDataLines2; i++) {
fgets(lineHolder, 128, secondFile);
if(strcmp(lineHolder, "\n") == 0) {
continue;
}
if(sscanf(lineHolder, "%40[^\n]",&storeSecondFileStuff[i]) == 0) {
printf("Unable to parse line %d of second file\n",i+2);
return EXIT_FAILURE;
}
lookup(theHash, &storeSecondFileStuff[i], hashTableSize);
}
printf("\n");
fclose(file);
fclose(secondFile);
return 0;
}
Thanks!
I think you have multiple problems. To start with, you might not be scanning your input line correctly. Change your line
if(sscanf(lineHolder, "%d, %40[^\n]", &libraryID,&tempString[i]) == 0)
to
if(sscanf(lineHolder, "%d, %40[^\n]", &libraryID, tempString) < 0)
that way, you will trap the situation where the sscanf function did not successfully convert both arguments - for example, if there is no comma in the input line. Note that sscanf returns the number of successful conversions; success would return a value of 2, so testing for <2 is the right way to go.
Note also that I changed &tempString[i] to tempString. The former points to some place along tempString - which only has 41 characters allocated to it. Yet you always allow up to 40 characters (plus '\0' to be written to it - so you will write past the end of the string. Since this is only a temporary variable, there is no sense in doing this. Just scan the input into the temp variable, then do whatever you need to do with it.
This means that your insert also changes, from
insert(libraryID, &tempString[i], hashTableSize, theHash);
to
insert(libraryID, tempString, hashTableSize, theHash);
Again, you need to do the same thing lower down in your code.
Here is an attempt at making the code work for you - see if this hits the spot. Note that all I really did was change the type of tempString and storeSecondFileStuff, and modified the way they were used in various function calls accordingly. I did not attempt to compile / run because of the complexity of the other files involved - but this should help a bit:
int main(int argc, char * argv[]) {
if (argc != 3) {
printf("Incorrect arguments, please specify 2 files to be read\n");
return EXIT_FAILURE;
}
FILE *file = fopen( argv[1], "r");
FILE *secondFile = fopen(argv[2], "r");
if (file == 0 || secondFile == 0) {
printf("Could not open a file\n");
return EXIT_FAILURE;
}
int numDataLines2;
int numDataLines;
int hashTableSize;
//First line of first file gives number of lines in file and
//size of hash table to be made
if(fscanf(file, "%d%d", &numDataLines, &hashTableSize) < 2) {
printf("Unable to parse first line of first file\n");
return EXIT_FAILURE;
}
ListHndl* theHash = newHash(hashTableSize);
int libraryID;
char **tempString = calloc(numDataLines,sizeof(char*)); // <<< ARRAY of pointers
char lineHolder[129];
//discard the new line which always shows up
fgets(lineHolder, 128, file);
for(int i = 0; i < numDataLines; i++) {
//Gets the whole line to be scanned with sscanf
fgets(lineHolder, 128, file);
tempString[i] = calloc(1, 41 * sizeof(char)); // <<< space for this string
//If the line consists of just a newline char, continue
if(strcmp(lineHolder, "\n") == 0 ) {
continue;
}
//Scans the line retrieved from fgets and placed in lineHolder
if(sscanf(lineHolder, "%d, %40[^\n]", &libraryID, tempString[i]) < 0){ // <<< changed
printf("Unable to parse line %d of first file\n",i+2);
return EXIT_FAILURE;
}
insert(libraryID, tempString[i], hashTableSize, theHash); // <<< changed
}
char String[41];
fgets(String, 40, secondFile);
numDataLines2 = atoi(String);
char **storeSecondFileStuff = calloc(numDataLines2, sizeof(char*)); // changed: again char **
for(int i = 0; i< numDataLines2; i++) {
fgets(lineHolder, 128, secondFile);
storeSecondFileStuff[i] = calloc(1, 41 * sizeof(char));
if(strcmp(lineHolder, "\n") == 0) {
continue;
}
if(sscanf(lineHolder, "%40[^\n]",storeSecondFileStuff[i]) == 0) {
printf("Unable to parse line %d of second file\n",i+2);
return EXIT_FAILURE;
}
lookup(theHash, storeSecondFileStuff[i], hashTableSize); // <<<< changed
}
printf("\n");
fclose(file);
fclose(secondFile);
return 0;
}
My program requires me to read a dat file with a list of numbers. My goal is to get each number and add them to an array. The file has around 100 numbers in this format:
1
2
3
(styling is a bit off sorry ;[ )
so far i have
int main()
{
double prices[1000];
int count,price;
FILE *file;
file = fopen("price.dat","r");
if(file == NULL)
{
printf("Error: can't open file to read\n");
}
else
{
printf("File prices.dat opened successfully to read\n");
}
if (file){
while (fscanf(file, "%d", &price)!= NULL){
count++;
prices[count]=price;
}
}
fclose(file);
}
Problem is that it continues adding the last number continuously. Any help?
You have several problems in your code. To name a few:
fscanf doesn't return a pointer so you shouldn't be comparing it with NULL. All scanf functions returns an integer which can be positive, zero or negative.
You don't initialize count so it will contain a seemingly random value.
Indexing of arrays starts a zero, so you should not increase the array index count until after the assignment.
The actual problem with not wanting to stop is because of the first point.
#include <stdio.h>
#include <string.h>
#define PRICES_LIST_MAX 1000
#define PRICES_FILE "price.dat"
int main()
{
double prices[PRICES_LIST_MAX];
int count = 0;
int i = 0;
FILE *file;
file = fopen(PRICES_FILE,"r");
if(!file)
{
perror("Error opening file");
return -1;
}
memset(prices, 0, sizeof(prices));
while (!feof(file) /* Check for the end of file*/
&&(count < PRICES_LIST_MAX)) /* To avoid memory corruption */
{
fscanf(file, "%lf", &(prices[count++]));
}
fclose(file);
/* Print the list */
printf("Prices count: %d\n", count);
for(i = 0; i < count; i++)
{
printf("Prices[%d] = %lf\n", i, prices[i]);
}
return 0;
}