I'm trying to make a program in c90 which will read some words from a txt file and copy them to a matrix array. It seems that the compilation is all right but there is a thread named "EXC_BAD_ACCESS(code=1 adress=0x68). can you help me figure out where the problem is??
int main(int argc, char *argv[]) {
FILE *input;
char words[10][30];
int i,a;
input=fopen("test.txt","rt");
for(i=0;i<10;i++){
a = fscanf(input,"%s", words[i]);
printf("%2d %s\n", a, words[i]);
}
fclose(input);
return 0;
}
Check that your file is actually being opened, otherwise printf() will try to print out random memory which may go beyond the bounds of what you have actually allocated and cause an error.
input = fopen("test.txt", "rt");
if (!input)
{
perror("Failed to open file");
exit(1);
}
You may also want to check that a == 1, i.e. that the fscanf() also succeeds.
Related
Could you help me with the creation of a text file as right now the *fp pointer to the file is returning NULL to the function fopen ?
Using the library errno.h and extern int errno I get "Value of errno: 22".
if (!fp)perror("fopen") gives me "Error opening file: Invalid argument".
In my main function I enter the name of the file:
void main()
{
float **x;
int i,j;
int l,c;
char name_file[30];
FILE *res;
/* some lines omitted */
printf("\nEnter the name of the file =>");
fflush (stdin);
fgets(name_file,30,stdin);
printf("Name of file : %s", name_file);
res=creation(name_file,l,c,x);
printf("\nThe created file\n");
readfile(res,name_file);
}
The function to create the text file:
FILE *creation(char *f_name,int l, int c, float **a) // l rows - c colums - a array
{ FILE *fp;
int i,j;
fp = fopen(f_name,"wt+"); // create for writing and reading
fflush(stdin);
/* The pointer to the file is NULL: */
if (!fp)perror("fopen"); // it's returning Invalid argument
printf("%d\n",fp); //0 ??
if(fp==NULL) { printf("File could not be created!\n"); exit(1); }
fflush(stdin);
for(i=0;i<l;i++)
{
for(j=0;j<c;j++)
{
fprintf(fp,"%3.2f",a[i][j]); // enter every score of the array in the text file
}
fprintf(fp,"\n");
}
return fp;
}
Function to read the file and check if it is correct:
**void readfile(FILE *fp,char *f_name)**
{
float a;
rewind(fp);
if(fp==NULL) { printf("File %s could not open\n",f_name); exit(1); }
while(fscanf(fp,"%3.2f",&a)!= EOF)
printf("\n%3.2f",a);
fclose(fp);
}
There are quite a few wrong things your code.
1.
The correct signatures of main are
int main(void);
int main(int argc, char **argv)
int main(int argc, char *argv[])
See What are the valid signatures for C's main() function?
2.
The behaviour of fflush(stdin) is undefined. See Using fflush(stdin).
fflush works with output buffers, it tells the OS that is should write
the buffered content. stdin is an input buffer, flushing makes no sense.
3.
Use fgets like this:
char name_file[30];
fgets(name_file, sizeof name_file, stdin);
It's more robust using sizeof name_file because this will give you always
the correct size. If you later change the declaration of name_file to
an char array with less than 30 spaces, but forget to change the size parameter in fgets, you
might end up with a buffer overflow.
4.
You are passing to creation the uninitialized pointer p that is pointing
to nowhere. In said function you cannot read nor write with the pointer a.
You need to allocate memory prior to the call of creation. At least judging
from the code you posted.
5.
fgets preserves the newline ('\n') character, so
name_file is containing the newline character. I really don't know if newline
is allowed in file names. I did a google search but found conflicting answers.
I don't think that you want to have newlines in your file names, anyway. It's
best to remove it before passing it to fopen (which might be the reason for
the error 22):
char name_file[30];
fgets(name_file, sizeof name_file, stdin);
int len = strlen(name_file);
if(name_file[len - 1] == '\n')
name_file[len - 1] = 0;
i am trying to create an program to generate empty files. but when it try to run the program it crashes after taking inputs from the console .
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int create(char* filename)
{
char filext[10];
printf("\nEnter File Extension :");
fgets(filext);
FILE* fp;
fp = fopen(strcat(filename,strcat(".",filext)),"w");
if(!fp)
{
return 0;
}
fclose(fp);
return 1;
}
int main(int argc , char* argv[])
{
int f;
int i;
char buffer[33];
if (argc == 3)
{
for(i = 0; i < atoi(argv[2]) ; i++)
{
f = create(strcat(argv[1],itoa(i,buffer,10)));
if(f==0)
{
printf("error in creating files . check uac!!!");
}
else{
printf("\nfile Created ...\n");
}
}
}
else{
printf("syntax Error");
}
return 0;
}
when I try to run this program I get the following output
F:\selfcreatedtools\filegen>gcc gen.c
F:\selfcreatedtools\filegen>a level 100
Enter File Extension :php
after entering the extension the program crashes.
i am a beginner in c programming.
Your main problem lies in the strcat(".",filext) part of fp = fopen(strcat(filename,strcat(".",filext)),"w");
Try
strcat(filename, ".");
strcat(filename, filext);
fp = fopen(filename, "w");
And it might be better if the function definition header was made
int create(char filename[SIZE]) (where SIZE is a value less than the size filename will be) instead of int create(char* filename) since you are using strcat() to modify the string in the user-defined function create(). You wouldn't want illegal memory accesses that would cause errors if the string encroaches upon the memory allotted to something else.
A similar problem is there with using strcat() to modify the string at argv[1] as pointed out by Jonathan Leffler for which BLUEPIXY has provided a solution in the comments.
I have to write a program witch reads from a file received by line and then it overwrites it with the read words uppercased.
This is my code
void toUpperCase(char* string) {
int i=0;
while(string[i])
{
string[i]=toupper(string[i]);
i++;
} }
int main(int argc, char** argv) {
if(argc==1)
{
puts("Error: INSERT PATH");
exit(0);
}
char* file=argv[1];
FILE* fd=fopen(file,"r+");
if(fd<0)
{
perror("Error opening file: ");
exit(0);
}
char buffer[30][30];
int i=0;
while(!feof(fd))
{
fscanf(fd,"%s",buffer[i]);
i++;
}
int j=0;
for(j=0; j<i; j++)
{
toUpperCase(buffer[j]);
fwrite(buffer[j],strlen(buffer[j]),1,fd);
}
fclose(fd);
return 0; }
but this program appends the words contained in buffer[][] instead of overwriting the file.
If the file contain was something like pippo pluto foo then, after the execution is pippo pluto fooPIPPOPLUTOFOO instead of PIPPO PLUTO FOO.
Where am i wrong? Thank you
You have to reset the file position indicator using fseek, as fscanf will advance it. Something like
fseek(fd, length_of_read_string, SEEK_CUR);
This allows you to read the file in chunks, but it will be tricky to get right. Or of course reset it to the file start because you read everything in 1 go:
fseek(fd, 0L, SEEK_SET);
I strongly recommend writing the modified data into a new file, and then after the program has run, delete the initial file and rename the new one. That will also take care of another issue with your program, you are reading the entire file into memory before handling it.
If you want to do in-place translation that doesn't change lengths, you can open the source file in two streams and then do read-chunk, write-chunk in lockstep. That has the advantage of being super-easy to convert to a non-in-place version that will work with nonseekable files too (stdin/stdout, pipes, and sockets).
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <ctype.h> //toupper
inline void upcaseStr(char* str){
for(;*str;str++) { *str=toupper(*str); }
}
int upcaseStream(FILE* in, FILE* out){
char buf[BUFSIZ]; //BUFSIZ is an implementation-defined constant for an optimal buffer size
while(fgets(buf, BUFSIZ, in)){
upcaseStr(buf);
if(fputs(buf, out) == EOF){ return 1; }
}
if(!feof){ return 1; }
return 0;
}
int main(int argc, char **argv)
{
//default in and out
FILE* in = stdin;
FILE* out = stdout;
if(argc == 2) {
in = fopen(argv[1], "r"); //for reading
out = fopen(argv[1], "r+"); //for writing (and reading) starting at the beginning
if(!(in && out)){
fprintf(stderr, "Error opening file %s for reading and writing: %s\n", argv[1], strerror(errno));
}
}
return upcaseStream(in, out);
}
If you do use the in-place version, then in the unlikely event that the if(fputs(buf, out) == EOF){ return 1; } line should return, you're screwed unless you have a backup copy of the file. :)
Note:
You shouldn't name your FILE pointers fd because C people will tend to think you mean "file descriptor". FILE is a struct around a file descriptor. A file descriptor is just an int that you can use for FILE access with the raw system calls. FILE streams are an abstraction layer on top of file descriptors--they aren't file descriptors.
As you read from the file, its internal position indicator gets moved. Once you start writing, you start writing from that position on, which happens to be at the end of the file. So you effectively append the data to the file.
Rewind the handle to reset the position indicator before writing into the file:
rewind(fp);
On a side note, you are reading the file incorrectly:
while(!feof(fd))
{
fscanf(fd,"%s",buffer[i]);
i++;
}
When you reach the end of the file, fscanf will return an error and not read anything, yet you still increment variable i, as if the read was successful. And then you check feof() for end-of-file, but i was already incremented.
Check feof() and return of fscanf() immediately after calling fscanf():
while(1)
{
int read = fscanf(fd,"%s",buffer[i]);
if( read != 1 )
//handle invalid read
if( feof(fd) )
break;
i++;
}
Think about what happens if the string is longer than 29 characters and/or the file contains more than 30 strings. char buffer[30][30];
Welcome to StackOverflow!
Reopening the stream with fopen with the "w" parameter:
fd=fopen(file, "w");
It opens the file and if there are any contents in the file, it clears them.
When I compile the program and run it, it does not print anything. I believe the problem is on the while but I can't understand what is wrong. It is supposed to convert hex to ASCII and then the encrypted message.
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int main(int argc, char **argv) {
int p;
//Opening a file
FILE*tp;
tp = fopen(argv[1], "r");
if(tp == NULL)
{
printf("Error opening file!\n");
return 0;
}
else
{
//Decryption code
while((p=fscanf(" %x",&p))!=EOF)
{
p=p >> 2;
p=p - 200;
printf(" %c",p);
}
}
return 1;
fclose(tp);
}
fscanf() returns number of input items successfully matched and assigned, not input items themselves. Also, as mentioned above, you need to pass file pointer to the function. Try this: while(fscanf(tp, "%x", &p) != EOF)
Looks like you need to specify and provide the FILE pointer "tp" to the fscanf function.
I'm coding a program to crack the CRC16. I've been having some problems with outputting the file and keep the calculated CRC16(have no idea why it changes when I write it to a file). So what I'm doing here is read the input file, writing it to a output file with some gibberish and then I read the output file again and calculate it's CRC16. If it matches with the desired CRC16, then it is done. However after a bunch of executions the fgets() method crashes with a Seg fault.
Anyone could help me? Please ignore the performance issues, this is a test.
int main(int argc, char* argv[]){
char outfile[strlen(argv[1])];
strcpy(outfile,argv[1]);
strcat(outfile,".crack");
char crc16[5];
strcpy(crc16,argv[2]);
char newcrc16[5];
char gebrish[80];
char cat[2];
int full = 1;
int p = 0;
int i,j,k;
for(i=32; i< 128;i++)
for(j=32; j< 128; j++)
for(k=32; k < 128; k++){
gebrish[0] =i;
gebrish[1] =j;
gebrish[2] =k;
gebrish[3] = '\n';
gebrish[4] ='\0';
boost::crc_16_type result;
FILE* file;
FILE* out;
char line[100];
printf("read out\n");
out = fopen(outfile,"w");
printf("read file\n");
file = fopen(argv[1],"r");
printf("wrt\n");
while(fgets(line,80,file) != NULL){
fputs(line,out);
}
fputs(gebrish,out);
fclose(file);
fclose(out);
printf("read gain\n");
out = fopen(outfile,"r");
while(fgets(line,80,out) != NULL){
result.process_bytes(line,strlen(line));
printf("%s",line);
}
int crc = result.checksum();
sprintf(newcrc16,"%x",crc);
printf("%s",newcrc16);
if(strcmp(crc16,newcrc16) == 0){
printf("%s",gebrish);
return 0;
}
}
return 0;
}
This causes a buffer overrun:
char outfile[strlen(argv[1])];
strcpy(outfile,argv[1]);
strcat(outfile,".crack");
as there is not enough space in outfile for terminating null character and ".crack". It will be overwriting memory it is not supposed to and may be the cause of the segmentation fault.
Change to:
char outfile[strlen(argv[1]) + 1 + 6];
strcpy(outfile,argv[1]);
strcat(outfile,".crack");
Before accessing argv elements ensure they have been provided by checking argc:
if (argc > 2)
{
/* Safe to use argv[1] and argv[2]. */
}
Check return values from fopen() also.
The error is most likely due to not checking the return value from open, and then calling fgets on a bad file. Returns from system calls should always be checked if subsequent operations depend on them. Even close can fail.
The problem is that I tried to Read and Write from the same file in different moments without calling fclose() after the use. This way after some execution of the loop it crashes with a STATUS_VIOLATION. I have no idea why it didn't crash right away, but all I did was add a flcose() after reading the file for the CRC16 calculation.