I've never had so much trouble writing data to files! I'm running GCC from MinGW, because I'm used to using GCC in Linux. I usually use the Linux system calls open(), write(), and read(), but I'm writing a Windows program now and I had trouble using read()/write() in Windows, so I'm just using the standard libraries. Anyway, the problem I'm having is I have no idea how to write to a file! I've defined "FILE *" variables, used fopen(), with "r+b", "wb", and "w+b", but I still cannot write to my output file with fwrite() or fprintf(). I don't know what I'm even doing wrong! Here's my source:
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#define DEBUG 1
/*** Global functions ***/
double highfreq(double deg);
/*** Global variables ***/
double sin_now;
unsigned int *ptr;
unsigned char *key, *infilename, *outfilename;
FILE *infile, *outfile, *keyfile;
const char *pipe_name="[pipe]";
int main(int argc, char *argv[]) {
unsigned int x, y, z;
if(argc!=3) {
fprintf(stderr, "Syntax error: %s <infile.txt> <outfile.wav>", argv[0]);
return 1;
}
if(argv[1][0]=='-') {
infile=stdin;
infilename=(unsigned char *)pipe_name;
}
else {
infilename=argv[1];
if((infile=fopen(infilename, "rb"))==NULL) {
fprintf(stderr, "Could not open input file for modulation.\n", infile);
return 2;
}
}
if(argv[2][0]=='-') {
outfile=stdout;
outfilename=(unsigned char *)pipe_name;
}
else {
outfilename=argv[2];
if((infile=fopen(outfilename, "wb"))==NULL) {
fprintf(stderr, "Could not open/create output file for modulation.\n", outfile);
return 3;
}
}
if(DEBUG) printf("Input file:\t%s\nOutput file:\t%s\n", infilename, outfilename);
fprintf(outfile, "Why won't this work!?\n");
fclose(infile);
fclose(outfile);
return 0;
}
double highfreq(double deg) {
double conv, rad;
conv=M_PI/180;
rad=deg*conv;
return sin(rad);
}
I'm eventually going to make a WAV file as output, hence the "highfreq()" function, but for now I can't even get it to write to a file! fprintf() returns with an error value of -1, if that helps anyone. I don't really understand, though because from what I read, this simply indicates there was an error, but nothing more.
outfilename=argv[2];
if((infile=fopen(outfilename, "wb"))==NULL) {
That's the second time in your code you assign the result of fopen to infile. You probably wanted outfile there.
Related
I tried to write a program in C that checks if a certain file is executable or not, if it is a shell script or a binary
<apue.h> is a header from the book Advanced Programming in the UNIX Environment
I don't think the approach is exactly right (if it's a shell script or binary). I think there is a more efficient solution. Which one do you think?
In addition, what other problems does the code have?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <apue.h>
void checkIfFileExists(const char *fileName);
int main (int argc,char *argv[])
{
char *fileName = argv[1];
if (argc < 2 )
{
err_quit("File to check not specified\n");
return 0;
}
if (argc > 2 )
{
err_quit("Too many arguments\n");
return 0;
}
checkIfFileExists(fileName);
return 0;
}
void checkIfFileExists(const char *fileName)
{
if(!access( fileName, F_OK ))
{
if(!access( fileName, X_OK ))
{
printf("The file %s is an executable\n",fileName);
//check if the file is binary or shell script
}
else
{
printf("The file %s is not an executable\n",fileName);
}
}
else
{
err_quit("The file %s was not found\n",fileName);
}
}
You can use the stat methods,
#include <sys/stat.h>
...
struct stat myf;
stat(<file>,&mf);
if( mf.st_mode & S_IXUSR )
printf("execute");
The output is a bitmap from which you can extract the file permission info
look at https://www.gnu.org/software/libc/manual/html_node/Permission-Bits.html
for the permission define available.
I want to create a text file with mulitple lines using system calls in C and populate it with the text provided as command line arguments.
This is what I wrote:
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define MAX_SZ 1024
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("Invalid Number of arguments\n");
printf("USAGE: ./a.out file_name \"msg\"\n");
} else {
int fd_creat, fd_open, fd_write;
char file_name[MAX_SZ];
char *msg = (char *)malloc(strlen(argv[2]) * sizeof(char));
strcpy(file_name, argv[1]);
fd_creat = creat(file_name, 0777);
if (fd_creat < 2) {
printf("ERROR: File could not be created\n");
} else {
fd_open = open(file_name, O_WRONLY);
strcpy(msg, argv[2]);
fd_write = write(fd_open, msg, strlen(msg));
close(fd_open);
}
}
return 0;
}
If I execute this program as:
./a.out test.txt "Foo\nBar"
It writes the whole thing into test.txt as it is. Basically, I want 'Foo' and 'Bar' in their separate lines.
There's two problems here:
The way you're handling arguments and failing to allocate enough memory for the data involved,
Interpreting escape sequences like \n correctly since the shell will give them to you as-is, raw.
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
// This moves overlapping strings from src -> dest but only
// if dest is before src
void cc_str_drag(char* dest, char* src) {
while (*dest) {
*dest = *src;
++dest;
++src;
}
}
// This interprets the \n sequence and can be extended to handle others, like
// \t, \\, or even \g.
void cc_interpret(char* str) {
for (;*str; ++str) {
// If this is a sequence start...
if (*str == '\\') {
// ...find out which one...
switch (str[1]) {
case 'n':
// Shift back...
cc_str_drag(str, &str[1]);
// ...and replace it.
*str = '\n';
break;
}
}
}
}
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("Invalid Number of arguments\n");
// Remember argv[0] is the name of the program
printf("USAGE: %s file_name \"msg\"\n", argv[0]);
return -1;
}
// Since it's not the 1970s, use fopen() and FILE*
FILE* output = fopen(argv[1], "w");
if (!output) {
printf("ERROR: File could not be created\n");
return -2;
}
// Copying here to avoid tampering with argv
char* str = strdup(argv[2]);
// Replace any escape sequences
cc_interpret(str);
// Then just dump it directly into the file
fwrite(str, 1, strlen(str), output);
fclose(output);
return 0;
}
Note the tools used here:
strdup is a way quicker method of copying a C string than malloc(strlen(s)) and then copying it. That's asking for dreaded off-by-one errors.
FILE* performs much better because it's buffered. open() is used for low-level operations that can't be buffered. Know when to use which tool.
Don't be afraid to write functions that manipulate string contents. C strings are really important to understand, not fear.
I am trying to write a program using Lex which recognizes some letters, numbers and do minor things. The problem is that the program does not recognizes anything. In fact, I changed the rules to a simple rule to recognizes everything, but still does nothing. What's happening? Maybe it's simple (it must be, there are few lines), but I am new with Lex and I am not able to fix it. Thanks
simple.l:
%{
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int count = 0;
%}
/*Reglas*/
%%
[a-zA-Z_]*[a-zA-Z_0-9]* { count++; printf("%s ", yytext); }
.* { count++; printf("%s ", yytext); }
%%
/*Procedimientos de usuario*/
int main(int argc, char * argv[]) {
FILE * yyin;
if(argc == 2) {
yyin =fopen(argv[1],"rt");
if(yyin == NULL) {
printf("File %s can not be opened\n", argv[1]);
exit(-1);
}
} else {
printf("Error in arguments");
exit(-1);
}
yylex();
printf("Counter : %d \n", count);
fclose(yyin);
return 0;
}
Imput file: example.txt
CSC104H1
CSC108H1
CSC204H1
CSC258H1
Also, I need to use ctrl+d to finish the program(as I saw in stackoverflow), if not, the program does not finish by itself.
int main(int argc, char * argv[]) {
FILE * yyin;
// ...
yyin = ....
}
Here, yyin is a local variable. The scanner is using the global variable with the same name, which this declaration is shadowing.
Delete the declaration and it will work fine.
Your first clue is that the scanner is evidently reading from standard input, not from the file you specified, which is why it waits for you to type an end-of-file indicator.
I have seen questions similar to this one on here before but I was unable to solve my problem from the answers to those.
I have a file libfoo.c from which I'm creating a shared object. Using gcc's __attribute__((constructor)), I'd like to print a message to a file when this shared object is loaded:
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
static char *term = NULL;
static void init (void) __attribute__((constructor));
static void
init (void)
{
FILE *f = fopen ("lib.log", "w");
if (f)
{
if (isatty (STDOUT_FILENO))
{
char *tmp = ttyname (STDERR_FILENO);
if (tmp && *tmp)
{
term = strdup (tmp); // nevermind the memory leak
fprintf (f, "Found terminal %s\n", term);
}
}
else
fprintf (f, "Failed to find terminal\n");
fclose(f);
}
}
void *
malloc (size_t size)
{
return NULL;
}
The dummy malloc implementation (to be extended later) should replace stdlib.h's malloc in another dummy program, whose source code resides in main.c:
#include <stdlib.h>
int main (void)
{
char *m = malloc(1024);
(void)m;
return 0;
}
I'm compling and linking both files as follows:
gcc -o main main.c
gcc -fpic -shared -o libfoo libfoo.c
And then when I execute the following no file is created and no output is logged:
LD_PRELOAD=$(readlink -f libfoo) ./main
What is going on here? As a sidenote: how could I try to debug a problem like this using ltrace? ltrace "LD_PRELOAD=... ./main" is not a valid command.
EDIT: What is going on here? It seems at least printf works inside the shared object, but only inside the setup function, if I call printf inside malloc the program segfaults. In trying to at least figure out what terminal stdout is connected to I did the following (inside the setup function):
// ...
char buf[100];
buf[readlink ("/proc/self/fd/1", buf, 100)] = '\0';
printf ("STDOUT (buf): %s\n", buf);
char *tmp = ttyname (1);
printf ("STDOUT (ttyname): %s, %s\n", tmp, strerror (errno));
// ...
This prints:
STDOUT (buf): /dev/pts/1
STDOUT (ttyname): (null), Success
According to the ttyname manpage, that second line of output should be impossible. Am I completely misunderstanding something here?
here is what I ran, created from your code, and it ran perfectly, generating a file: lib.log
The contents of the file: lib.log
Found terminal /dev/pts/1
and now, the code I ran:
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
static char *term = NULL;
static void init (void) __attribute__((constructor));
static void init (void)
{
FILE *f = fopen ("lib.log", "w");
if (f)
{
if (isatty (STDOUT_FILENO))
{
char *tmp = ttyname (STDERR_FILENO);
if (tmp && *tmp)
{
term = strdup (tmp); // nevermind the memory leak
fprintf (f, "Found terminal %s\n", temp);
}
}
else
fprintf (f, "Failed to find terminal\n");
fclose(f);
}
else
{
perror( "fopen failed" );
}
}
void *
myMalloc (size_t size)
{
(void)size;
return NULL;
}
int main (void)
{
char *m = myMalloc(1024);
(void)m;
return 0;
}
Of course, your posted code is missing a header file. Such a header file should be referenced/included by your main.c file and your libfoo.c file
I have to make a program that manages info it obtains from a file, but I'm using Turbo C 3.0 which is ancient, so I'm getting errors trying to write to the file, here is my code:
#include <conio.h>
#include <stdio.h>
void main(){
clrscr();
int c;
FILE *datos;
datos = fopen("datos.txt","w");
c = fgetc (datos);
printf("%d",c);
fclose(datos);
getch();
}
Whenever I print it I get -1 as return. I know this must be something really simple but I'm having issues.
Check to make sure you have a valid file:
// use "r" for reading, "w" for writing
datos = fopen("datos.txt", "r");
if (datos)
{
int ch = fgetc(datos);
if (ch != EOF)
printf("%d\n", c);
else
printf("End of file!\n");
}
else
{
printf("Failed to open datos.txt for reading.\n");
}
You open the file in write only mode ("w"), but you are trying to read the file with fgetc.
Either open the file in read-only mode ("r"), then read the data, close the file, and open it again in write only mode to write it. Or open the file in a mode that support both reading and writing - check the documentation of Turbo-C for more info.
Try opening the file for "read" instead:
#include <conio.h>
#include <stdio.h>
#include <errno.h>
int main(){
int c;
FILE *datos;
clrscr();
datos = fopen("datos.txt","r");
if (!datos) {
printf ("Open failed, errno=%d\n", errno);
return 1;
}
c = fgetc (datos);
printf("%d",c);
fclose(datos);
getch();
return 0;
}
If it still fails, tell us the error#.
'include statements
main(){
char we;
char intt;
ifstream q("xyz.txt");
for (we=0;we<100;we++){
q >> intt;
printf("%c",q);
}
getch();
}