I am trying to print the value of a double and an int. Both are pointers because I use sscanf to get the information for each value. My code compiles, but I have 2 warnings. The warnings are:
a4Functions.c:47:9: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘int *’ [-Wformat=]
a4Functions.c:47:9: warning: format ‘%lf’ expects argument of type ‘double’, but argument 5 has type ‘double *’ [-Wformat=]
and my code is :
void parser(int argc, char ** argv)
{
FILE * songs;
char songString[ROOM_STRING_LENGTH];
char * theString;
char artist[ROOM_STRING_LENGTH];
char title[ROOM_STRING_LENGTH];
int * lengthPointer;
double * sizePointer;
char type[ROOM_STRING_LENGTH];
lengthPointer = 0;
sizePointer = 0;
songs = fopen(argv[1], "r");
if(songs == NULL)/*returns an error if file wasnt opened*/
{
printf("error opening file\n");
}
while(fgets(songString, ROOM_STRING_LENGTH, songs) != NULL)/*gets one string at a time until fgets equals NULL*/
{
theString = malloc((sizeof(char)*(strlen(songString)+1)));
strcpy(theString, songString);
sscanf(theString, "%s,%s,%d,%lf,%s", artist, title, lengthPointer, sizePointer, type);
printf("%s,%s,%d,%lf,%s\n", artist, title, lengthPointer, sizePointer, type);
}
}
You need to dereference the pointer first.
printf("%s,%s,%d,%lf,%s\n", artist, title, *lengthPointer, *sizePointer, type);
What I would do in this case is not using pointer for both variables, but just regular variables, and use & operator in the sscanf call.
Also you need to allocate memory first before using the lengthPointer and sizePointer. And don't forget to free them after you finished.
Need space for the data and need to pass pointers to sscanf()
// int * lengthPointer;
int lengthPointer;
// double * sizePointer;
double sizePointer;
...
//sscanf(theString, "%s,%s,%d,%lf,%s", artist, title, lengthPointer, sizePointer, type);
sscanf(theString, "%s,%s,%d,%lf,%s", artist, title, &lengthPointer, &sizePointer, type);
// No change
printf("%s,%s,%d,%lf,%s\n", artist, title, lengthPointer, sizePointer, type);
BTW: Be sure to free theString when you are done.
free(theString);
}
Related
here is the code
#include <stdio.h>
#include <string.h>
int main()
{
int val;
struct info{
char model[50];
int price;
char color[30];
}car[11];
int i;
for(i=0;i<11;i++)
{
printf("Enter model name:\n");
scanf("%s",&car[i].model);
printf("Enter price:\n");
scanf("%d",&car[i].price);
printf("Enter color:\n");
scanf("%s",&car[i].color);
}
printf("\nThe red cars are:\n");
for(i=0;i<11;i++)
{
val=strcmp("red",tolower(car[i].color));
if(0==val)
{
printf("%d. %s\n",i+1,car[i].model);
}
}
return 0;
}
also I tried using gets for string input but it doesn't seem to work.
Here are the warnings:
*main.c:17:17: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[50]’ [-Wformat=]
scanf("%s",&car[i].model);
main.c:21:17: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[30]’ [-Wformat=]
scanf("%s",&car[i].color);
main.c:26:34: warning: passing argument 1 of ‘tolower’ makes integer from pointer without a cast [-Wint-conversion]
val=strcmp("red",tolower(car[i].color));
In file included from main.c:4:0:
/usr/include/ctype.h:124:12: note: expected ‘int’ but argument is of type ‘char *’
extern int tolower (int __c) __THROW;
main.c:26:26: warning: passing argument 2 of ‘strcmp’ makes pointer from integer without a cast [-Wint-conversion]
val=strcmp("red",tolower(car[i].color));
In file included from main.c:2:0:
/usr/include/string.h:144:12: note: expected ‘const char *’ but argument is of type ‘int’
extern int strcmp (const char *__s1, const char *__s2)
You posted your compiler output. Good. Let's look at all those errors:
main.c:17:17: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[50]’
Most of the time, when you call scanf, you need & on the variable being stored, but %s is an exception. (Explanation elsewhere.) Get rid of the &: scanf("%s",car[i].model);
main.c:26:34: warning: passing argument 1 of ‘tolower’ makes integer from pointer without a cast
This is your main problem. Your program as written will never work. tolower expects a single character to convert, but you're passing it a pointer instead. (You're passing it a pointer to the entire string you want to convert.)
/usr/include/ctype.h:124:12: note: expected ‘int’ but argument is of type ‘char *’
This is another message explaining the tolower problem.
main.c:26:26: warning: passing argument 2 of ‘strcmp’ makes pointer from integer without a cast
tolower returns the single character it has converted. But strcmp expects an entire string.
/usr/include/string.h:144:12: note: expected ‘const char *’ but argument is of type ‘int’
This is another message explaining the tolower/strcmp problem.
How to fix this? There is not a standard function (that I can remember) that converts an entire string to lowercase. You'd have to write that yourself. Another option is to use a version of strcmp that compares the strings without regard to case. Two such functions (neither of which is quite standard, however) are strcasecmp and stricmp.
tolower only works with char not string, so use the function on every char of the string.
#include <string.h>
#include <stdio.h>
#include <ctype.h>
int strcicmp(char const *a, char const *b)
{
if (!a && !b)
return 0
else if (!a || !b)
return -1
for (;; a++, b++) {
int d = tolower((unsigned char)*a) - tolower((unsigned char)*b);
if (d != 0 || !*a)
return d;
}
}
int main()
{
int val;
struct info{
char model[50];
int price;
char color[30];
}car[11];
int i;
for(i=0;i<11;i++)
{
printf("Enter model name:\n");
scanf("%s",&car[i].model);
printf("Enter price:\n");
scanf("%d",&car[i].price);
printf("Enter color:\n");
scanf("%s",&car[i].color);
}
printf("\nThe red cars are:\n");
for(i=0;i<11;i++)
{
val=strcicmp(car[i].color, "red");
if(0==val)
{
printf("%d. %s\n",i+1,car[i].model);
}
}
return 0;
}
how to fix?
warning:
incompatible pointer
types passing 'char [16]' to parameter of type 'FILE *'
(aka 'struct __sFILE *') [-Wincompatible-pointer-types]
fread(buffer,1,512,data);
^~~~
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/
SDKs/MacOSX10.13.sdk/usr/include/stdio.h:247:90: note:
passing argument to parameter '__stream' here
...__ptr, size_t __size, size_t __nitems, FILE * __restrict __stream);
^
1 warning generated.
here is my code:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
char readDATA[64];
char buffer[8];
char data[16];
FILE *fl = fopen(data,"r");
fgets(readDATA,64,fl);
fread(buffer,1,512,data);
printf("%s",readDATA);
return 0;
}
I try to open a path or "random" file please help.
According to manual page of fread()
The function fread() reads nmemb elements of data, each size bytes
long, from the stream pointed to by stream, storing them at the loca‐
tion given by ptr.
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
Last argument of fread() is the FILE *stream that means file from where you want to read something and store into buffer.
Replace
fread(buffer,1,512,data); /* last argument is wrong */
with
fread(buffer,1,512,f1);
Also check the return value of fopen()
FILE *f1 = fopen("data","r"); /* it will try to open a file called "data" in current working directory, you can take input from user also */
if(f1 == NULL) {
fprintf(stderr, "file not present\n");
return 0;
}
your intention may be like this
char data[16];/* it doesn't contain anything, so take the input from user or assign directly */
printf("enter the file name\n");
scanf("%s",data);
FILE *f1 = fopen(data,"r");
if(f1 == NULL) {
fprintf(stderr, "file not present\n");
return 0;
}
I'm trying to implement my own printf, I have an issue handling wide char %S.
void my_printf(char *format, ...)
{
char *traverse;
va_list arg;
va_start(arg, format);
traverse = format;
while (*traverse)
{
if (*traverse == '%')
{
*traverse++;
if (*traverse == 'S')
printf("%S\n", va_arg(arg, wchar_t));
*traverse++;
}
else
putchar(*traverse++);
}
va_end(arg);
}
warning: format specifies type 'wchar_t *' (aka 'int *') but the argument has type 'wchar_t' (aka 'int') [-Wformat]
printf("%S\n", va_arg(arg, wchar_t));
when I use following code printf works fine.
printf("%S\n", L"Some String");
You're passing a pointer and retrieving an integer. The types of L"Some String" and va_arg(arg, wchar_t), do not match.
Retrieve a pointer instead:
va_arg(arg, wchar_t*)
The line *traverse++; is not correct, the dereference is redundant. It should be simply: traverse++;
On a side note, your code doesn't do any input checking and a malicious string will cause undefined behavior. This will happen if the character '%' is the last character, the iterator traverse will point to one beyond the last element in the array and the check while (*traverse) will dereference it.
I have the following code which is failing with EXC_BAD_ACCESS (code=1) and has the following warning:
Incompatible integer to pointer conversion passing 'int' to parameter of type 'const char *'
char *printb(fmt,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
{
static char string[256];
sprintf(string,fmt,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10);
return(string);
}
printb is being called by this code:
if (gotargs) fname = *(argv++);
else do {
printf("file name #%d: ", i+1);
fname = gets(inbuf);
} while (*fname == 0);
if ((gbuf=fopen(fname, "r")) == NULL)
error(printb("I can't find '%s'", fname));
printf("reading '%s'...\n", fname);
if (fgets((lp = inbuf), 512, gbuf) == NULL)
error("file is empty");
Also, how can I convert the gets() to fgets() properly?
Thanks
Well, why did you use the ancient-style function declaration
char *printb(fmt,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
{
?
This declaration declares all arguments as ints. Your attempts to pass a char * pointers to this function will only lead to disaster. Moreover, you are not supplying all parameters in your printb calls, which is another disaster.
It looks like you are attempting to implement a function with variable number of arguments. Specifically for that the language supports ... parameter declaration. Read about variadic functions and va_list.
Your function would be implemented along the lines of
char *printb(const char *fmt, ...)
{
static char string[256];
va_list va;
va_start(va, fmt);
vsprintf(string, fmt, va);
va_end(va);
return string;
}
or better
...
vsnprintf(string, sizeof string, fmt, va);
...
Although the idea of returning a pointer to an internal static buffer is also flawed.
Meanwhile, trying to "emulate" variadic arguments by your method is hopeless. It won't work.
I am working on a log parsing program that retrieves the file to open by combining an environment variable and a preset string in order to provide the full path to the file, but i am having trouble getting fopen to take out the output from sprintf which i am using to combine the environment variable and the preset string,so i was wondering if anyone could offer advice on what i should do to get this to work properly? thanks! (i have just begun teaching myself C over the last few weeks, so im open to any tips no matter how obvious they should be to me)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _GNU_SOURCE
void main(int argc, char *argv[], char *envp[])
{
FILE *fd; // File pointer
char *name;
char *filename[];
name = getenv("MCEXEC_PLAYERNAME");
sprintf(filename,"/home/minecraft/freedonia/playerdata/deathlog-%s.txt",name);
char buff[1024];
if ((fd = fopen(filename, "r")) != NULL) // open file
{
fseek(fd, 0, SEEK_SET); // make sure start from 0
while(!feof(fd))
{
memset(buff, 0x00, 1024); // clean buffer
fscanf(fd, "%[^\n]\n", buff); // read file *prefer using fscanf
}
printf("Last Line :: %s\n", buff);
}
else
printf( "fail" );
}
here is the error i get while compiling using gcc
lastline.c: In function ‘main’:
lastline.c:9: error: array size missing in ‘filename’
lastline.c:11: warning: passing argument 1 of ‘sprintf’ from incompatible pointer type
/usr/include/stdio.h:341: note: expected ‘char * __restrict__’ but argument is of type ‘char **’
lastline.c:13: warning: passing argument 1 of ‘fopen’ from incompatible pointer type
/usr/include/stdio.h:249: note: expected ‘const char * __restrict__’ but argument is of type ‘char **’
char *filename[];
declares an array of pointers to char of unknown size. You need an array of char to sprintf to, of sufficient known length. Declare
char filename[1000]; // assuming 1000 is large enough
or
char *filename;
as a pointer to char and malloc sufficient memory after you have gotten the name,
filename = malloc(sizeof "/home/minecraft/freedonia/playerdata/deathlog-.txt" - 1 + strlen(name) + 1);
if (!filename) exit(EXIT_FAILURE);
to avoid unpleasant surprises if name turns out longer than expected.