bad file descriptor from fread - c

I try to use read() to get some characters from file just for learning this API. I have create a file called "file" in the same directory and it contains 1000 characters. But I got an error saying:
read: %m: Bad file descriptor
Here is the code:
#include <stdio.h>
#include <error.h>
int read_indent(int sockfd){
int sport, cport;
char user[2], rtype[2], addinfo[2];
char buffer[17];
if(read(sockfd, buffer, sizeof(buffer)) <= 0) {
perror("read: %m");
return -1;
}
buffer[sizeof(buffer)-1] = '\0';
sscanf(buffer, "%d:%d:%s:%s:%s", &sport, &cport, rtype, user, addinfo);
printf("%d:%d:%s:%s:%s", sport, cport, rtype, user, addinfo);
return 0;
}
int main(){
FILE *file_pt = fopen("file", "r");
if(file_pt == NULL) { printf("fopen error\n"); return -1;}
char buf[128];
int a = read_indent(file_pt);
fclose(file_pt);
return 0;
}
UPDATE 1: Compilation message
test.c: In function ‘main’:
test.c:27:2: warning: passing argument 1 of ‘read_indent’ makes integer from pointer without a cast [enabled by default]
int a = read_indent(file_pt);
^
test.c:4:5: note: expected ‘int’ but argument is of type ‘struct FILE *’
int read_indent(int sockfd){

Your read_indent function takes a file descriptor, but you're passing in a FILE* pointer. Try turning the FILE* pointer into a file descriptor using fileno:
int a = read_indent(fileno(file_pt));

Related

Why isn't my code producing a random sequence of numbers between 1 and N? No file is produced. What is the error in my code? What am I doing wrong?

The goal of the program is to generate a random sequence of numbers between 1 and N, where N is passed as an argument to the program, and write the resulting sequence to a file.
My file isn't produced. What am I doing wrong? Are there any errors in my code? Is there something wrong with my code? Am I outputting the file correctly?
/*01*/ //
/*02*/ // random_sequence_v6.c
/*03*/ // Generate a random sequence of all numbers between 1 to N
/*04*/ //
/*05*/ #include "stdio.h"
/*06*/ #include "stdint.h"
/*07*/ #include "stdlib.h"
/*08*/ #include "stdint.h"
/*09*/ #include "sys/types.h"
/*10*/ #include "sys/stat.h"
/*11*/ #include "fcntl.h"
/*12*/ #include "assert.h"
/*13*/ #include "inttypes.h"
/*14*/
/*15*/ typedef uint64_t value_t;
/*16*/
/*17*/ value_t* generate_sequence(int num_values)
/*18*/ {
/*19*/ assert(num_values > 0);
/*20*/ value_t* data = calloc(num_values, sizeof(int));
/*21*/ for (int i = 0; i <= num_values; i++) {
/*22*/ data[i] = i;
/*23*/ }
/*24*/ return data;
/*25*/ }
/*26*/
/*27*/ int random_value(int min, int max)
/*28*/ {
/*29*/ int random_number;
/*30*/ do {
/*31*/ random_number = rand();
/*32*/ } while ((random_number <= min) || (random_number >= max));
return random_number;
/*33*/ }
/*34*/
/*35*/ void randomize_sequence(value_t* sequence, int num_values)
/*36*/ {
/*37*/ // Fisher-Yates
/*38*/ for(int i = 0; i < num_values-2; i++) {
/*39*/ int random_index = random_value(i, num_values-1);
/*40*/ // Swap them
int temp = sequence[i];
/*41*/ sequence[i] = sequence[random_index];
/*42*/ sequence[random_index] = temp;
/*43*/ }
/*44*/ }
/*45*/
/*46*/ int main(int argc, char* argv[])
/*47*/ {
/*48*/ int num_values = strtoul(argv[1], NULL, 10);
/*49*/ value_t* pValues = generate_sequence(num_values);
/*50*/
/*51*/ randomize_sequence(pValues, num_values);
/*52*/
/*53*/ // Record results
/*54*/ FILE *fd = fopen("results.txt", "w+");
/*55*/ for (int i = 0; i < num_values; i++) {
/*56*/ fprintf("%i = %"PRIu64"\n", i, pValues[i]);
/*57*/ }
/*58*/ fclose(fd);
/*59*/
/*60*/ return EXIT_SUCCESS;
/*71*/ }
the posted code contains LOTS of serious problems. Specifically:
gcc -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled2.c" -o "untitled2.o"
untitled2.c: In function ‘generate_sequence’:
untitled2.c:20:35: warning: conversion to ‘size_t {aka long unsigned int}’ from ‘int’ may change the sign of the result [-Wsign-conversion]
/*20*/ value_t* data = calloc(num_values, sizeof(int));
^~~~~~~~~~
untitled2.c:22:25: warning: conversion to ‘value_t {aka long unsigned int}’ from ‘int’ may change the sign of the result [-Wsign-conversion]
/*22*/ data[i] = i;
^
untitled2.c: In function ‘randomize_sequence’:
untitled2.c:42:27: warning: conversion to ‘int’ from ‘value_t {aka long unsigned int}’ may alter its value [-Wconversion]
int temp = sequence[i];
^~~~~~~~
untitled2.c:44:41: warning: conversion to ‘value_t {aka long unsigned int}’ from ‘int’ may change the sign of the result [-Wsign-conversion]
/*42*/ sequence[random_index] = temp;
^~~~
untitled2.c: In function ‘main’:
untitled2.c:50:29: warning: conversion to ‘int’ from ‘long unsigned int’ may alter its value [-Wconversion]
/*48*/ int num_values = strtoul(argv[1], NULL, 10);
^~~~~~~
untitled2.c:58:24: warning: passing argument 1 of ‘fprintf’ from incompatible pointer type [-Wincompatible-pointer-types]
/*56*/ fprintf("%i = %"PRIu64"\n", i, pValues[i]);
^~~~~~~~
In file included from untitled2.c:5:0:
/usr/include/stdio.h:312:12: note: expected ‘FILE * restrict {aka struct _IO_FILE * restrict}’ but argument is of type ‘char *’
extern int fprintf (FILE *__restrict __stream,
^~~~~~~
untitled2.c:58:44: warning: passing argument 2 of ‘fprintf’ makes pointer from integer without a cast [-Wint-conversion]
/*56*/ fprintf("%i = %"PRIu64"\n", i, pValues[i]);
^
In file included from untitled2.c:5:0:
/usr/include/stdio.h:312:12: note: expected ‘const char * restrict’ but argument is of type ‘int’
extern int fprintf (FILE *__restrict __stream,
^~~~~~~
untitled2.c:48:21: warning: unused parameter ‘argc’ [-Wunused-parameter]
/*46*/ int main(int argc, char* argv[])
^~~~
Compilation finished successfully.
Notice that final message: Compilation finished successfully. This only means that the compiler applied some 'workaround' to each of the problems, it does NOT mean that the 'workaround' was correct.
Please correct your code so it cleanly compiles, then post a EDIT to your question
a few hints:
never access beyond argv[0] without first checking argc to assure the user actually entered the expected command line parameter.
the syntax for fprintf() is int fprintf(FILE *stream, const char *format, ...);
the syntax for strtoul() is unsigned long int strtoul(const char *nptr, char **endptr, int base);
also, regarding:
FILE *fd = fopen("results.txt", "w+");
always check (!=NULL) the returned value. If failed (I.E. ==NULL) then call
perror( "fopen failed" );
so both the error message and the text reason the system thinks the error occurred to stderr.

How do I merge two sorted files into one sorted file?

Being more specific, I want to merge two sorted lists of integers into a third list that is also sorted. I can't figure out why my code isn't working! Here's some example of entries and the code I made:
File1:
1
2
3
4
5
6
File2:
7
8
9
9
9
10
C code:
#include <stdio.h>
#include <stdlib.h>
void merge(char* arq1, char* arq2){
FILE* final;
final = fopen("merge.txt",'w');
FILE* f1 = fopen(arq1,'rt');
FILE* f2 = fopen(arq2,'rt');
if(!f1 || !f2) exit(1);
// n1 and n2 represents the actual value that's been read. r1 and r2 the status of each file.
int n1,n2,r1,r2,equal;
r1 = fscanf(f1,"%d",&n1);
r2 = fscanf(f2,"%d",&n2);
while(r1 || r2){
if((!r1) || (n2 < n1)){
fprintf(final,"%d ",n2);
r2 = fscanf(f2,"%d",&n2);
}else if((!r2) || (n1 < n2)){
fprintf(final,"%d ",n1);
r1 = fscanf(f1,"%d",&n1);
}else{
equal = n1;
fprintf(final,"%d ",equal);
while(n1 == equal) r1 = fscanf(f1,"%d",&n1);
while(n2 == equal) r2 = fscanf(f2,"%d",&n2);
}
}
fclose(final);
fclose(f1);
fclose(f2);
}
int main(int argc, char const *argv[]){
merge("merge1.txt","merge2.txt");
return 0;
}
The algorithm is supposed to work as follows:
While at least one of the files still has content, its content would be then saved at the merge.txt file. If file 1 and 2 would possess the same content, I'd save the content and make the 2 files read until they find a different value so that the merged file does not have repeated values.
How do I merge two sorted files into one sorted file?
the mode-argument for fopen() should be a string.
fscanf() can return EOF(-1) on error or EOF
On failure, the value of the target variable(s) for fscanf() is undefined.
#include <stdio.h>
#include <stdlib.h>
void merge(char* arq1, char* arq2){
FILE *final;
final = fopen("merge.txt", "w"); // <<--(1)
FILE *f1 = fopen(arq1, "rt"); // <<--(1)
FILE *f2 = fopen(arq2, "rt"); // <<--(1)
if(!f1 || !f2 || !final) exit(1); // <<--(1)
// n1 and n2 represents the actual value that's been read. r1 and r2 the status of each file.
int n1,n2,r1,r2,equal;
r1 = fscanf(f1, "%d", &n1);
r2 = fscanf(f2, "%d", &n2);
while(r1>0 || r2>0){ // <<--(2)
if(r1 < 1 || n2 < n1){ // <<--(2)
fprintf(final, "%d ", n2);
r2 = fscanf(f2, "%d", &n2);
}else if(r2 < 1 || n1 < n2){ // <<--(2)
fprintf(final, "%d ", n1);
r1 = fscanf(f1, "%d", &n1);
}else{
equal = n1;
fprintf(final, "%d ", equal);
while(n1 == equal && r1 > 0) r1 = fscanf(f1, "%d", &n1); // <<--(2,3)
while(n2 == equal && r2 > 0) r2 = fscanf(f2, "%d", &n2); // <<--(2,3)
}
}
fclose(final);
fclose(f1);
fclose(f2);
}
int main(int argc, char const *argv[]){
merge("merge1.txt","merge2.txt");
return 0;
}
the OPs posted code fails to cleanly compile!
Here is the output from the compiler:
gcc -ggdb -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled.c"
untitled.c: In function ‘merge’:
untitled.c:6:31: warning: passing argument 2 of ‘fopen’ makes pointer from integer without a cast [-Wint-conversion]
final = fopen("merge.txt",'w');
^~~
In file included from untitled.c:1:0:
/usr/include/stdio.h:232:14: note: expected ‘const char * restrict’ but argument is of type ‘int’
extern FILE *fopen (const char *__restrict __filename,
^~~~~
untitled.c:7:27: warning: multi-character character constant [-Wmultichar]
FILE* f1 = fopen(arq1,'rt');
^~~~
untitled.c:7:27: warning: passing argument 2 of ‘fopen’ makes pointer from integer without a cast [-Wint-conversion]
In file included from untitled.c:1:0:
/usr/include/stdio.h:232:14: note: expected ‘const char * restrict’ but argument is of type ‘int’
extern FILE *fopen (const char *__restrict __filename,
^~~~~
untitled.c:8:27: warning: multi-character character constant [-Wmultichar]
FILE* f2 = fopen(arq2,'rt');
^~~~
untitled.c:8:27: warning: passing argument 2 of ‘fopen’ makes pointer from integer without a cast [-Wint-conversion]
In file included from untitled.c:1:0:
/usr/include/stdio.h:232:14: note: expected ‘const char * restrict’ but argument is of type ‘int’
extern FILE *fopen (const char *__restrict __filename,
^~~~~
untitled.c: In function ‘main’:
untitled.c:33:14: warning: unused parameter ‘argc’ [-Wunused-parameter]
int main(int argc, char const *argv[]){
^~~~
untitled.c:33:32: warning: unused parameter ‘argv’ [-Wunused-parameter]
int main(int argc, char const *argv[]){
^~~~
regarding:
final = fopen("merge.txt",'w');
the 'mode' parameter must be a string. Suggest using double quotes around the 'mode' parameter:
final = fopen("merge.txt","w");
regarding:
FILE* f1 = fopen(arq1,'rt');
as before, the 'mode' parameter must be a string. Suggest:
FILE* f1 = fopen(arq1,"rt");
for the main() function, since the parameters are not being used, suggest using the signature:
int main( void )
When compiling, always enable the warnings, then fix those warnings

C Pointer Error

The program below is supposed to read a txt file and put the data in a struct. But it gives an pointer error. It gives an error in strcpy() about pointers. I'm new in C. Whats wrong?
#include <stdio.h>
#include <string.h>
int main()
{
struct citydata {
char city[20];
int temp;
};
struct citydata values[15];
struct citydata Avg;
struct citydata high;
struct citydata low;
FILE* inp;
int reccount = 0;
int x = 0;
char s;
int n;
inp = fopen("mydata.txt", "r");
if (!inp) {
printf("Unable ot open file\n");
}
while (fscanf(inp, "%s %d", s, &n) != EOF) {
strcpy(values[x].city, s);
values[x].temp = n;
x++;
}
fclose(inp);
}
Don't ignore compiler warnings.
When if you compile this code (say, with gcc), you get the following warnings:
test.c:27:24: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Wformat=]
while (fscanf(inp, "%s %d", s, &n) != EOF) {
^
test.c:28:32: warning: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion]
strcpy(values[x].city, s);
^
In file included from test.c:2:0:
/usr/include/string.h:125:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
so, as comments suggest, you can't scan directly into the struct; you can only scan into simpler types the C standard libraries recognizes: integer, floating-point numbers, char * strings etc. Similarly, you can't perform a string copy from your structs, which are not strings.
C is a strongly-typed language with very few allowed implicit conversions. In some cases, you are able to pass integers instead of floats or vice-versa, but nothing "magically converts" into a string, or is "magically parsed" from a string.
... and there are other issues:
Note #EdHeal 's comment: If your fopen() fails, you mustn't continue running the rest of the code. Either you should exit(EXIT_FAILURE); or wrap the rest of the code in main() within an else() block.
You should printf error messages to the standard error stream, so instead of printf("error message here") it should fprintf(stderr,"error message here"). Also, the standard C library places an error code you can get as the errno variable, or you can have an error message printed to the standard error stream with the perror() function. There are a few other related related functions (like strerror(), `err() etc.) which I will not get into here.
make some mistakes with pointers=)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct citydata
{
char *city;
int temp;
} citydata;
int main()
{
char *s;
citydata *values;
values = (citydata*)malloc(sizeof(citydata) * 16);
FILE * inp;
int reccount = 0;
int x = 0;
int n;
inp = fopen("mydata.txt", "r");
if(!inp)
printf("Unable ot open file\n");
while (fscanf(inp,"%s %d",s, &n) != EOF)
{
values[x].city = (char*)malloc(sizeof(char) * 20);
strcpy(values[x].city, s);
values[x].temp = n;
x++;
}
fclose(inp);
}

Reading data from a file into a structure array (C)

I'm trying to build a simple function that will take in a data file, and assign various values from the data file into a global array of structures. However, I'm having trouble getting it to work quite right. I've written what I believe is most of the needed code, but my test line printf("time is %d\n", BP[i].time); simply reads out "Time is 0." 10 times, leading me to believe the values aren't getting assigned to the structure array like I imagined they would be.
How can I proceed further?
Example Data File (.txt):
0001 553 200
0002 552 100
.... ... ...
Current Code:
#include <stdio.h>
#include <stdlib.h>
// Function Prototype
void readFileBP(char fileName[1000]);
// Definition of BP Structure
struct bloodPressure
{
int *time;
int *sys;
int *dia;
}BP[50]; // end struct BP
int main()
{
char fileName[1000] = "C:\\Users\\User\\Desktop\\DataFiles\\BP_1.txt";
readFileBP(fileName);
int i = 0;
for (i; i<10; i++)
{
printf("Time is %d\n", BP[i].time);
}
} // end int main()
void readFileBP(char fileName[1000])
{
FILE *filePtr; // declare file pointer
int time;
int sys;
int dia;
int position = 0;
if (filePtr = fopen(fileName, "r") == NULL) // error check opening file
{
printf("Opening file failed. Please reenter filename.");
exit(1);
} // end if
while (fscanf(filePtr, "%d, %d, %d", &time, &sys, &dia) != EOF) // read in BP values
{
BP[position].time = time;
BP[position].sys = sys;
BP[position].dia = dia;
position++;
} // end while
fclose(filePtr);
} // end void readFile()
Compile with warnings enabled. You should get something like that:
gsamaras#gsamaras-A15:~$ gcc -Wall -o px px.c
px.c: In function ‘main’:
px.c:22:5: warning: statement with no effect [-Wunused-value]
for (i; i<10; i++)
^
px.c:24:9: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]
printf("Time is %d\n", BP[i].time);
^
px.c: In function ‘readFileBP’:
px.c:37:17: warning: assignment makes pointer from integer without a cast [enabled by default]
if (filePtr = fopen(fileName, "r") == NULL) // error check opening file
^
px.c:37:5: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
if (filePtr = fopen(fileName, "r") == NULL) // error check opening file
^
px.c:45:27: warning: assignment makes pointer from integer without a cast [enabled by default]
BP[position].time = time;
^
px.c:46:26: warning: assignment makes pointer from integer without a cast [enabled by default]
BP[position].sys = sys;
^
px.c:47:26: warning: assignment makes pointer from integer without a cast [enabled by default]
BP[position].dia = dia;
^
px.c: In function ‘main’:
px.c:26:1: warning: control reaches end of non-void function [-Wreturn-type]
} // end int main()
^
Isn't that enough to get you started? It was for me! :)
I made some changes and ran it just now.
#include <stdio.h>
#include <stdlib.h>
// Function Prototype
void readFileBP(char fileName[1000]);
// Definition of BP Structure
struct bloodPressure
{
int time;
int sys;
int dia;
}; // end struct BP
struct bloodPressure BP[50];
int main()
{
char *fileName = "file.txt";
readFileBP(fileName);
int i = 0;
for (i; i<10; i++)
{
printf("Time is %d\n", BP[i].time);
}
getch();
}
void readFileBP(char fileName[1000])
{
FILE *filePtr; // declare file pointer
int time=0;
int sys=0;
int dia=0;
int position = 0;
filePtr= fopen(fileName,"r");
while (fscanf(filePtr, "%d, %d, %d", &time, &sys, &dia) != EOF) // read in BP values
{
BP[position].time = time;
BP[position].sys = sys;
BP[position].dia = dia;
position++;
} // end while
fclose(filePtr);
} // end void readFile()
The output is now:
Time is 1
Time is 553
Time is 200
Time is 2
Time is 552
Time is 100
Time is 0
Time is 0
Time is 0
Time is 0
try changing the line :
while (fscanf(filePtr, "%d, %d, %d", &time, &sys, &dia) != EOF)
to
while (fscanf(filePtr, "%d%d%d", &time, &sys, &dia) != EOF)
also here's what i tried out and it seems to work based on the tests i've done
#include <stdio.h>
#include <stdlib.h>
#define MAX_ARRAY_SIZE 50
typedef struct BloodPressure
{
int time;
int sys;
int dia;
}BloodPressure;
BloodPressure bloodPressure[MAX_ARRAY_SIZE];
void ReadFile(char *fileName);
int main(int argc, char *argv[])
{
char *fileName = "BP_1.txt";
ReadFile(fileName);
int i = 0;
for (i = 0; i < MAX_ARRAY_SIZE; i++)
{
printf("Dia is : %d\n", bloodPressure[i].dia);
printf("Sys is : %d\n", bloodPressure[i].sys);
printf("Time is : %d\n", bloodPressure[i].time);
printf("\n");
}
exit(EXIT_SUCCESS);
}
void ReadFile(char *fileName)
{
FILE *filePtr = NULL;
int i = 0;
if ((filePtr = fopen(fileName, "r")) == NULL)
{
printf("Error : Unable to open %s for reading\n");
exit(EXIT_FAILURE);
}
while (fscanf(filePtr, "%d%d%d", &bloodPressure[i].dia, &bloodPressure[i].sys, &bloodPressure[i].time) != EOF)
{
i++;
}
fclose(filePtr);
}

SQLite3 connecting to C program and using inner loops to iterate through results - what do?

:D
I am reading definitive guide to sqlite (owens, allen) and decided to actually experiment with some of the code in this fine book and ran into some compilation problems. I was hoping to crowd source some of these problems and learn some C and SQLite at the same time! whoa yeah!
I receive the following mysterious compilation errors upon compiling this:
gcc mo.c -o m -lsqlite3
mo.c: In function ‘main’:
mo.c:22:44: error: ‘nrows’ undeclared (first use in this function)
mo.c:22:44: note: each undeclared identifier is reported only once for each function
it appears in
mo.c:22:52: error: ‘ncols’ undeclared (first use in this function)
mo.c:22:2: warning: passing argument 3 of ‘sqlite3_get_table’ from incompatible pointer
type [enabled by default]
/usr/local/include/sqlite3.h:2084:16: note: expected ‘char ***’ but argument is of
type ‘char * (*)[50]’
I am most confused by "warning: passing argument 3 of 'sqlite3_get_table' from incompatible pointer type [enabled by default]" and "note: expected 'char *' but argument is of type 'char * (*)[50]'
the program in question is below: can you make it go stackoverflow?
<===================================================================================>
#include <stdio.h>
#include <sqlite3.h>
#include <stdlib.h>
int main()
{
sqlite3 *db;
char *zErr;
int rc;
char *sql;
char *result[50];
int j=0;
int i=0;
rc = sqlite3_open("foods-backup.db", &db);
if(rc) {
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
exit(1);
}
rc = sqlite3_get_table(db, sql, &result, &nrows, &ncols, &zErr);
for(i; i < nrows; i++) {
for(j; j < ncols; j++) {
/* the i+1 term skips over the first record,
which is the column headers */
fprintf(stdout, "%s", result[(i+1)*ncols + j]);
}
}
if(rc != SQLITE_OK) {
if (zErr != NULL) {
fprintf(stderr, "SQL error: %s\n", zErr);
sqlite3_free(zErr);
}
}
/* Free memory */
sqlite3_free_table(result);
// close database connection or something and return everything is okay i guess
sqlite3_close(db);
return 0;
} // end main
The errors which you are getting are because of
1. nrows, ncols variables are not declared. They should be declared as integers.
2. result variable should be declared as char ** rather than char *result[50].
So comment out your result array pointer declaration and copy below two lines. Hope this helps.
int nrows, ncols;
char **result;
http://www.sqlite.org/c3ref/free_table.html
int sqlite3_get_table(
sqlite3 *db, /* An open database */
const char *zSql, /* SQL to be evaluated */
char ***pazResult, /* Results of the query */
int *pnRow, /* Number of result rows written here */
int *pnColumn, /* Number of result columns written here */
char **pzErrmsg /* Error msg written here */
);

Resources