How to open file in C program? - c

The code here is a code from a website. Since I was facing an issue with my origin code, I ended up trying this implementation from a website. But turns out I have the same issue with this program too
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num;
FILE *fptr;
if ((fptr = fopen("D:\\TestFile\\test.txt","r")) == NULL){
printf("Error! opening file\n");
perror(fptr);
// Program exits if the file pointer returns NULL.
exit(1);
}
fscanf(fptr,"%d", &num);
printf("Value of n=%d\n", num);
printf("%s\n", fptr);
fclose(fptr);
return 0;
}
I am stuck with the if condition i.e., whatever I do I am not able to read the file except the root directory. Even though I specify the path, it still looks for the file under root directory.
I am not sure why it's not working, provided the same code works fine in Linux

I see 2 mistakes, the one related to perror mentioned in the comments, and the last printf. Now if the program is still not working, it could be interesting to check the error or to get the program output.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num;
FILE *fptr;
if ((fptr = fopen("D:\\TestFile\\test.txt","r")) == NULL){
// printf("Error! opening file\n");
// perror(fptr); // MISTAKE-1: perror parameter is a string
perror("Error! opening file");
// Program exits if the file pointer returns NULL.
exit(1);
}
fscanf(fptr,"%d", &num);
printf("Value of n=%d\n", num);
//printf("%s\n", fptr); // MISTAKE-2: fptr is not a string
fclose(fptr);
return 0;
}

the posted code does not cleanly compile!
Here is the results of compiling with many of the warnings enabled:
gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled1.c" -o "untitled1.o"
untitled1.c: In function ‘main’:
untitled1.c:11:16: warning: passing argument 1 of ‘perror’ from incompatible pointer type [-Wincompatible-pointer-types]
11 | perror(fptr);
| ^~~~
| |
| FILE * {aka struct _IO_FILE *}
In file included from untitled1.c:1:
/usr/include/stdio.h:775:33: note: expected ‘const char *’ but argument is of type ‘FILE *’ {aka ‘struct _IO_FILE *’}
775 | extern void perror (const char *__s);
| ~~~~~~~~~~~~^~~
untitled1.c:19:13: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘FILE *’ {aka ‘struct _IO_FILE *’} [-Wformat=]
19 | printf("%s\n", fptr);
| ~^ ~~~~
| | |
| | FILE * {aka struct _IO_FILE *}
| char *
Compilation finished successfully.
Note; the statement: Compilation finished successfully. just means the compiler applied some work around to each of the problems. It does NOT mean the correct code was produced.

Related

How to make VSCODE show gcc output when compiling

I'm trying to edit my tasks.json and/or launch.json to output warnings gcc would usually show when compiling C code with -Wall and -Wextra flags using Run Without Debugging.
When using the the Run Without Debugging option in VSCODE it seems to compile the program using the flags set in my workspace tasks.json file but it doesn't show me the output of gcc.
There's a Task - build active file-tab in the terminal section but it just shows:
> Executing task: C/C++: gcc build active file <
Starting build...
Build finished successfully.
Terminal will be reused by tasks, press any key to close it.
Example code:
#include <stdio.h>
int main(void)
{
int ten = 10;
int two = 2;
printf("Doing it right:\t");
printf("%d minus %d is %d\n\n", ten, 2, ten - two);
printf("Doing it wrong:\t");
printf("%d minus %d is %d\n",ten); // Two arguments missing
return 0;
}
Example of the desired output upon compiling:
example.c: In function ‘main’:
example.c:13:23: warning: format ‘%d’ expects a matching ‘int’ argument [-Wformat=]
13 | printf("%d minus %d is %d\n",ten); // Two arguments missing
| ~^
| |
| int
example.c:13:29: warning: format ‘%d’ expects a matching ‘int’ argument [-Wformat=]
13 | printf("%d minus %d is %d\n",ten); // Two arguments missing
| ~^
| |
| int

Why calling SetConsoleCtrlHandler() triggers a warning?

#include <windows.h>
BOOL MyCtrlHandler(DWORD ctrlType) {
return TRUE;
}
int main(void) {
SetConsoleCtrlHandler(MyCtrlHandler, TRUE);
return 0;
}
The function signature matches the doc:
The PHANDLER_ROUTINE type defines a pointer to this callback function. HandlerRoutine is a placeholder for the application-defined function name.
If I cross-compile it with MinGW in 64 bits, it works:
$ x86_64-w64-mingw32-gcc ctrl.c
$
But in 32 bits, I get a warning:
$ i686-w64-mingw32-gcc ctrl.c
ctrl.c: In function ‘main’:
ctrl.c:8:27: warning: passing argument 1 of ‘SetConsoleCtrlHandler’ from incompatible pointer type [-Wincompatible-pointer-types]
8 | SetConsoleCtrlHandler(MyCtrlHandler, TRUE);
| ^~~~~~~~~~~~~
| |
| BOOL (*)(DWORD) {aka int (*)(long unsigned int)}
In file included from /usr/share/mingw-w64/include/windows.h:74,
from ctrl.c:1:
/usr/share/mingw-w64/include/wincon.h:249:68: note: expected ‘PHANDLER_ROUTINE’ but argument is of type ‘BOOL (*)(DWORD)’ {aka ‘int (*)(long unsigned int)’}
249 | WINBASEAPI WINBOOL WINAPI SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,WINBOOL Add);
|
$
I don't understand why, because MyCtrlHandler should have the same type as PHANDLER_ROUTINE.
The problem here is the difference between __cdecl and __stdcall. You must have lucked out with the default calling convention on your one successful attempt to compile. You need:
BOOL WINAPI MyCtrlHandler(DWORD ctrlType) {
return TRUE;
}

GCC errors when trying to compile checkinstall on Cygwin

I'm running Cygwin on top of Windows 7. I'm having trouble trying to install the checkinstall utility from source, and the culprit appears to be gcc.
When I run /.configure, I get the error:
-bash: ./configure: No such file or directory
So I continue with make, and get output that fails with lots of errors, presumably caused by gcc. The output can be seen in its entirety here, but below are the first and last few lines of it.
$ make
for file in locale/checkinstall-*.po ; do \
case ${file} in \
locale/checkinstall-template.po) ;; \
*) \
out=`echo $file | sed -s 's/po/mo/'` ; \
msgfmt -o ${out} ${file} ; \
if [ $? != 0 ] ; then \
exit 1 ; \
fi ; \
;; \
esac ; \
done
make -C installwatch
make[1]: Entering directory '/cygdrive/b/Users/Me/Desktop/checkinstall-1.6.2/installwatch'
gcc -Wall -c -D_GNU_SOURCE -DPIC -fPIC -D_REENTRANT -DVERSION=\"0.7.0beta7\" installwatch.c
In file included from /usr/local/include/sys/param.h:33:0,
from installwatch.c:31:
/usr/local/include/sys/types.h:10:2: error: #error Only Win32 target is supported!
#error Only Win32 target is supported!
^~~~~
In file included from /usr/local/include/sys/param.h:33:0,
from installwatch.c:31:
/usr/local/include/sys/types.h:90:3: error: unknown type name ‘time_t’
time_t tv_sec; /* Seconds */
^~~~~~
In file included from installwatch.c:33:0:
/usr/local/include/sys/stat.h:10:2: error: #error Only Win32 target is supported!
#error Only Win32 target is supported!
^~~~~
In file included from /usr/local/include/sys/stat.h:14:0,
from installwatch.c:33:
/usr/local/include/io.h:199:28: error: expected ‘,’ or ‘;’ before ‘_findfirst32’
_CRTIMP intptr_t __cdecl _findfirst32(const char *_Filename,struct _finddata32_t *_FindData);
^~~~~~~~~~~~
...
installwatch.c: In function ‘fopen’:
installwatch.c:2560:51: error: expected ‘)’ before ‘result’
logg("%" PRIdPTR "\tfopen\t%s\t#%s\n",(intptr_t)result,
^~~~~~
installwatch.c:2560:8: warning: format ‘%s’ expects a matching ‘char *’ argument [-Wformat=]
logg("%" PRIdPTR "\tfopen\t%s\t#%s\n",(intptr_t)result,
^~~
installwatch.c:2560:8: warning: format ‘%s’ expects a matching ‘char *’ argument [-Wformat=]
installwatch.c:2575:51: error: expected ‘)’ before ‘result’
logg("%" PRIdPTR "\tfopen\t%s\t#%s\n",(intptr_t)result,
^~~~~~
installwatch.c:2575:8: warning: format ‘%s’ expects a matching ‘char *’ argument [-Wformat=]
logg("%" PRIdPTR "\tfopen\t%s\t#%s\n",(intptr_t)result,
^~~
installwatch.c:2575:8: warning: format ‘%s’ expects a matching ‘char *’ argument [-Wformat=]
installwatch.c: At top level:
installwatch.c:2600:7: error: conflicting types for ‘getcwd’
char *getcwd(char *buffer,size_t size) {
^~~~~~
In file included from /usr/local/include/sys/stat.h:14:0,
from installwatch.c:33:
/usr/local/include/io.h:279:17: note: previous declaration of ‘getcwd’ was here
char *__cdecl getcwd (char *, int) __MINGW_ATTRIB_DEPRECATED_MSVC2005;
^~~~~~
installwatch.c:2664:30: error: unknown type name ‘uid_t’
int lchown(const char *path, uid_t owner, gid_t group) {
^~~~~
installwatch.c:2664:43: error: unknown type name ‘gid_t’
int lchown(const char *path, uid_t owner, gid_t group) {
^~~~~
installwatch.c:2749:5: error: conflicting types for ‘mkdir’
int mkdir(const char *pathname, mode_t mode) {
^~~~~
In file included from /usr/local/include/sys/stat.h:14:0,
from installwatch.c:33:
/usr/local/include/io.h:280:15: note: previous declaration of ‘mkdir’ was here
int __cdecl mkdir (const char *) __MINGW_ATTRIB_DEPRECATED_MSVC2005;
^~~~~
installwatch.c:2983:7: error: conflicting types for ‘realpath’
char *realpath(const char *file_name,char *resolved_name) {
^~~~~~~~
installwatch.c:556:6: note: previous implicit declaration of ‘realpath’ was here
if(!realpath(path,resolved_path)) {
^~~~~~~~
installwatch.c:3309:5: error: conflicting types for ‘utime’
int utime (const char *pathname, const struct utimbuf *newtimes) {
^~~~~
In file included from /usr/local/include/utime.h:6:0,
from installwatch.c:47:
/usr/local/include/sys/utime.h:115:26: note: previous definition of ‘utime’ was here
__CRT_INLINE int __cdecl utime(const char *_Filename,struct utimbuf *_Utimbuf) {
^~~~~
installwatch.c: In function ‘true_stat’:
installwatch.c:153:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
installwatch.c: In function ‘true_lstat’:
installwatch.c:161:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
installwatch.c: In function ‘true_mknod’:
installwatch.c:157:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
In file included from installwatch.c:35:0:
installwatch.c: In function ‘open’:
installwatch.c:2842:20: warning: ‘mode_t {aka short unsigned int}’ is promoted to ‘int’ when passed through ‘...’
mode = va_arg(ap, mode_t);
^
installwatch.c:2842:20: note: (so you should pass ‘int’ not ‘mode_t {aka short unsigned int}’ to ‘va_arg’)
installwatch.c:2842:20: note: if this code is reached, the program will abort
At top level:
installwatch.c:1040:12: warning: ‘__instw_printdirent64’ defined but not used [-Wunused-function]
static int __instw_printdirent64(struct dirent64 *entry) {
^~~~~~~~~~~~~~~~~~~~~
make[1]: *** [Makefile:22: installwatch.o] Error 1
make[1]: Leaving directory '/cygdrive/b/Users/Me/Desktop/checkinstall-1.6.2/installwatch'
make: *** [Makefile:11: all] Error 2
I'm sorry in advance if I'm going about this the wrong way, but I'm completely out of my depth with this code and the errors being thrown. I've tried using the Cygwin installer to reinstall gcc_core and other gcc packages several times to no effect.
I was in the process of using this guide to compile the latest version of gcc from source before I ran into fatal errors with that too, and decided to start from the beginning and determine whether the problem can be solved without adding yet more bloat to my Cygwin installation. Thanks in advance, it's much appreciated.
The checkinstall app does not appear to be configured to run on cygwin. It is configured for several specific Linux distribution families, and has a generic source release.
I have downloaded and unpacked the checkinstall-1.6.2.tar.gz file; it expands into the checkinstall-1.6.2 directory. There you find the checkinstall shell script. I don't have the time to wade through several thousand lines of shell code. It appears to require you build and install the installwatch program, which I guess will register a file change handler in order to identify all new and changed files and directories. I suspect that handler would need to change to work properly in cygwin. You might have success posting to one of the Cygwin mailing lists.
HTH
Doug

Conflicting types for text to binary converter?

I am trying to create a program that takes a text file and converts it to a binary file. I have created the method to do so, but when I pass it the input and output files, I get a few errors:
unix1% gcc -Wall -Wextra main.c
main.c: In function 'main':
main.c:23:3: warning: implicit declaration of function 'txtbin'
main.c:23:8: warning: assignment makes pointer from integer without a cast
main.c: At top level:
main.c:30:7: error: conflicting types for 'txtbin'
main.c:23:10: note: previous implicit declaration of 'txtbin' was here
main.c: In function 'txtbin':
main.c:40:7: error: incompatible types when assigning to type 'struct FILE *' from type 'FILE'
main.c:41:7: error: incompatible types when assigning to type 'struct FILE *' from type 'FILE'
main.c:54:5: warning: implicit declaration of function 'strlen'
main.c:54:14: warning: incompatible implicit declaration of built-in function 'strlen'
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#define MAXLEN 255
#define MINLEN 0
#define NUMCHAR 1
#define NUMBYTE 4
int main(int argc, char * argv[]){
FILE* txtf;
FILE* binf;
if(argc != 4){
fprintf(stderr, "Check usage");exit(1);
}
if((txtf =fopen(argv[2], "w+"))==NULL){
fprintf(stderr, "Could not open text file: %s\n", argv[2]);exit(1);
}
if((binf =fopen(argv[3], "w+b"))==NULL){
fprintf(stderr, "could not open binary file: %s\n", argv[3]);
}
binf = txtbin(txtf,binf);
//bintxt();
return 0;
}
FILE* txtbin(FILE in, FILE out){
FILE *ifp;
FILE *ofp;
int tmpint = 0;
unsigned char tmpchr = 0;
char tmpstr[MAXLEN];
ifp = in;
ofp = out;
while(fscanf(ifp, "%s \t %i \n", tmpstr, &tmpint) == 2){
tmpchr = strlen(tmpstr);
fwrite(&tmpchr, sizeof(tmpchr), NUMCHAR, ofp);
fwrite(tmpstr, sizeof(tmpstr[0]), tmpchr, ofp);
fwrite(&tmpint, sizeof(tmpint), NUMBYTE, ofp);
}
fclose(ifp);
fclose(ofp);
return ofp;
}
I know I have a few warnings, but I am most concerned with just getting the program to output the binary file for the respective text file.
By the way, here is the text file:
hello 32
goodbye 56
my 1
name 77
is 91
andrew 3
hello 32
goodbye 56
my 1
name 77
is 91
andrew 3
You need to have a declaration of the function before calling it, add this before main()
FILE* txtbin(FILE in, FILE out);
also, tmpchr should be size_t instead of unsigned char and, this line
fwrite(&tmpint, sizeof(tmpint), NUMBYTE, ofp);
is attempting to write 4 integers, instead of 1, the correct way is
fwrite(&tmpint, sizeof(tmpint), 1, ofp);
And the correct txtbin() signature would be
FILE* txtbin(FILE* in, FILE* out);

Cannot Work with mxmlGetText and mxmlGetElemet in mxml

#include <mxml.h>
#include <stdio.h>
void main()
{
FILE *fp;
mxml_node_t *tree;
mxml_node_t *node = NULL;
fp = fopen("1.xml", "r");
tree = mxmlLoadFile(NULL, fp, MXML_OPAQUE_CALLBACK);
node = tree;
fprintf(stderr, "Element::%s\n", mxmlGetElement(node));
fprintf(stderr, "Value::%s\n", mxmlGetText(node, 0));
}
Above is My Code snippet ... Error is
xmlparsing.c: In function ‘main’:
xmlparsing.c:20:2: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Wformat]
xmlparsing.c:21:2: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Wformat]
/tmp/ccAYsMOB.o: In function `main':
xmlparsing.c:(.text+0x58): undefined reference to `mxmlGetElement'
xmlparsing.c:(.text+0x8c): undefined reference to `mxmlGetText'
collect2: ld returned 1 exit status
Already included the mxml.h than why undefined reference? I searched about this functions on the Internet, and links show me that it's in mxml.h header file.
Your problem is with your Linker, see that last message:
collect2: ld returned 1 exit status
You need to inform the gcc (which is a call to a compiler and linker about the include path and the library path.
The include path is where mxml.h is found, this will be done with:
-I<path/to/include/mxml.h>
The library path is given with:
-L<path/to/shared/libmxml.a>
So in total you should have:
gcc yourfile.c -I <path/to/include/mxml.h> -L <path/to/shared/libmxml.a>
You can include other paths as needed.

Resources