I'm getting a confusing error message. I'm running MinGW on Windows XP 32-bit. When I attempt to compile the following code, I get an error message "./hello.c: line 4: Syntax error near unexpected token '('". Line 4 is at int main(...), I can't figure out what unexpected token is "near '('". I've tried using int main(void), but I get the same message. However, if I compile it without the "char string..." and "data = fputs(...)" and have it read from a given text file, it compiles without issue.
What I'm trying to accomplish is to read from a file where the filename is given by an external source, i.e. php. Eventually I'm going to be working this into an Apache module with a parser that I've made, hence the call from php, but I wanted to fool around and build some template code to work with before I got to that part.
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
FILE *fp;
//char string = "JD"; commented out
char data;
//printf("Type in your filename: "); also commented out
//scanf("%s", &argv); also commented out
if(argc >= 2)
{
fp = fopen("sample.txt", "r"); //switched to reading a given file
}
while((data = getchar()) != EOF)
{
fgets(data, sizeof(data), fp);
// data = fputs(string, fp);
}
if (fp==NULL) /* error opening file returns NULL */
{
printf("Could not open player file!\n"); /* error message */
return 1; /* exit with failure */
}
/* while we're not at end of file */
while (fgets(data, sizeof(string), fp) != NULL)
{
printf(data); /* print the string */
}
fclose(fp); /* close the file */
return 0; /* success */
}
Okay, I tried writing a simple "Hello World" program, but I'm still getting the same error message with it which makes me think the error message isn't being caused by my code at all.
#include <stdio.h>
int main(void) //still getting a syntax error before unexpected token '('
{
printf("Hello, world!");
return 0;
}
There is problem with your logic . the "exploit" array would contain "./myotherAAAAAAAAAAAAAAAAAAAA:" which you are passing to system ..so problem are bound to happen
strncpy(command, "./myotherfile ", 9);
only copies the first 9 chars. Replace that with
strcpy(command, "./myotherfile ");
which should do what you want.
P.S. I suspect that you originally had
strncpy(command, "./myfile ", 9);
which would have worked, and you didn't change the 9 when you changed the length of the file name. There are entire books written on why couplings like this are a bad idea and what to do instead. In this case the simplest solution is to use strcpy so you don't need to mention the length.
I think you are trying to run ./motherfile...Then when you concatenate it with "exploit" name becomes "./myotherAAAAAAAAAAAAAAAAAAA " and not "./myotherfile AAAAAAAAAAAAAAAAAAAA", to give space concatenate it with a space first.
Related
Today I decided to learn to code for the first time in my life. I decided to learn C. I have created a small program that checks a txt file for a specific value. If it finds that value then it will tell you that that specific value has been found.
What I would like to do is that I can put multiple files go through this program. I want this program to be able to scan all files in a folder for a specific string and display what files contain that string (basically a file index)
I just started today and I'm 15 years old so I don't know if my assumptions are correct on how this can be done and I'm sorry if it may sound stupid but I have been thinking of maybe creating a thread for every directory I put into this program and each thread individually runs that code on the single file and then it displays all the directories in which the string can be found.
I have been looking into threading but I don't quite understand it. Here's the working code for one file at a time. Does anyone know how to make this work as I want it?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
//searches for this string in a txt file
char searchforthis[200];
//file name to display at output
char ch, file_name[200];
FILE *fp;
//Asks for full directory of txt file (example: C:\users\...) and reads that file.
//fp is content of file
printf("Enter name of a file you wish to check:\n");
gets(file_name);
fp = fopen(file_name, "r"); // read mode
//If there's no data inside the file it displays following error message
if (fp == NULL)
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
//asks for string (what has to be searched)
printf("Enter what you want to search: \n");
scanf("%s", searchforthis);
char* p;
// Find first occurrence of searchforthis in fp
p = strstr(searchforthis, fp);
// Prints the result
if (p) {
printf("This Value was found in following file:\n%s", file_name);
} else
printf("This Value has not been found.\n");
fclose(fp);
return 0;
}
This line,
p = strstr(searchforthis, fp);
is wrong. strstr() is defined as, char *strstr(const char *haystack, const char *needle), no file pointers in it.
Forget about gets(), its prone to overflow, reference, Why is the gets function so dangerous that it should not be used?.
Your scanf("%s",...) is equally dangerous to using gets() as you don't limit the character to be read. Instead, you could re-format it as,
scanf("%199s", searchforthis); /* 199 characters + \0 to mark the end of the string */
Also check the return value of scanf() , in case an input error occurs, final code should look like this,
if (scanf("%199s", searchforthis) != 1)
{
exit(EXIT_FAILURE);
}
It is even better, if you use fgets() for this, though keep in mind that fgets() will also save the newline character in the buffer, you are going to have to strip it manually.
To actually perform checks on the file, you have to read the file line by line, by using a function like, fgets() or fscanf(), or POSIX getline() and then use strstr() on each line to determine if you have a match or not, something like this should work,
char *p;
char buff[500];
int flag = 0, lines = 1;
while (fgets(buff, sizeof(buff), fp) != NULL)
{
size_t len = strlen(buff); /* get the length of the string */
if (len > 0 && buff[len - 1] == '\n') /* check if the last character is the newline character */
{
buff[len - 1] = '\0'; /* place \0 in the place of \n */
}
p = strstr(buff, searchforthis);
if (p != NULL)
{
/* match - set flag to 1 */
flag = 1;
break;
}
}
if (flag == 0)
{
printf("This Value has not been found.\n");
}
else
{
printf("This Value was found in following file:\n%s", file_name);
}
flag is used to determine whether or not searchforthis exists in the file.
Side note, if the line contains more than 499 characters, you will need a larger buffer, or a different function, consider getline() for that case, or even a custom one reading character by character.
If you want to do this for multiple files, you have to place the whole process in a loop. For example,
for (int i = 0; i < 5; i++) /* this will execute 5 times */
{
printf("Enter name of a file you wish to check:\n");
...
}
I wrote a program that asks the user to enter the full pathname of a file. It will then attempt to open that file from the pathname string provided. I used the standard error checking that most books have recommended, which is to close the program if fopen() returns NULL (which it will do in the case that the file does not exist). When I run the program and enter some random characters when prompted (obviously not a valid filename) my program hangs with a runtime error because it's trying to open that file that doesn't exist.
What is the point of the standard error check (pfile == NULL) if your program has already crashed when it calls fopen()? See below code.
I'm using LabWindows CVI 2017 as my enfironment which uses the clang compiler. See image of run time error.
#include <stdio.h>
#include <string.h>
#define MAX 200
int main (void){
char buffer[MAX];
int len = 0;
FILE *pfile = NULL;
printf("please enter the full pathname of the file you wish to process.\n");
fgets(buffer, MAX, stdin);
len = strlen(buffer);
buffer[len - 1] = '\0';
pfile = fopen(buffer, "r");
if(pfile == NULL){
printf("not a valid filename, press any key to exit.");
getchar();
return -1;
}
int sum = 0;
int c = 0;
while((c = fgetc(pfile)) != EOF){
sum += sizeof(c);
}
printf("the size of your file is %d\n", sum);
getchar();
return 0;
}
You are doing the proper error handling. Your program is valid in that respect. However, your IDE does some extra error checking, which is the cause of the behavior you're seeing.
The usual rules for error checking in these sorts of situations are:
Do check for error returns. (You're doing that.)
Do print a useful error message. (You're doing that.)
Print error messages to stderr.
If the error involves a file, do include the filename in the error message.
If the error involves a function that sets errno, do print the "perror" text" ("No such file or directory", etc.).
If you're writing a tool that will be combined into larger scripts, do include the program's name in the error message.
If the error occurs due to an input file you're reading, do print the name of that file and the line number.
Adopting rules 1 through 6, an improved version of your error check would be
if(pfile == NULL) {
fprintf(stderr, "%s: can't open %s: %s\n", progname, buffer, strerror(errno));
return EXIT_FAILURE;
}
For this to work you'll need both of:
#include <string.h>
#include <errno.h>
If that's too much work, a simpler way is just to call
perror(buffer);
although this falls down somewhat on rules 2, 6, and 7.
I am trying to write a simple C program that loads a text-file, prints the first line to screen, waits for the user to press enter and then prints the next line, and so on.
As only argument it accepts a text-file that is loaded as a stream "database". I use the getline()-function for this, according to this example. It compiles fine, successfully loads the text-file, but the program never enters the while-loop and then exits.
#include <stdio.h>
#include <stdlib.h>
FILE *database = NULL; // input file
int main(int argc, char *argv[])
{
/* assuming the user obeyed syntax and gave input-file as first argument*/
char *input = argv[1];
/* Initializing input/database file */
database = fopen(input, "r");
if(database == NULL)
{
fprintf(stderr, "Something went wrong with reading the database/input file. Does it exist?\n");
exit(EXIT_FAILURE);
}
printf("INFO: database file %s loaded.\n", input);
/* Crucial part printing line after line */
char *line = NULL;
size_t len = 0;
ssize_t read;
while((read = getline(&line, &len, database)) != -1)
{
printf("INFO: Retrieved line of length %zu :\n", read);
printf("%s \n", line);
char confirm; // wait for user keystroke to proceed
scanf("%c", &confirm);
// no need to do anything with "confirm"
}
/* tidy up */
free(line);
fclose(database);
exit(EXIT_SUCCESS);
}
I tried it with fgets() -- I can also post that code --, but same thing there: it never enters the while-loop.
It might be something very obvious; I am new to programming.
I use the gcc-compiler on Kali Linux.
Change your scanf with fgetline using stdin as your file parameter.
You should step through this in a debugger, to make sure your claim that it never enters the while loop is correct.
If it truly never enters the while loop, it is necessarily because getline() has returned -1. Either the file is truly empty, or you have an error reading the file.
man getline says:
On success, getline() and getdelim() return the number of
characters
read, including the delimiter character, but not including the termiā
nating null byte ('\0'). This value can be used to handle embedded
null bytes in the line read.
Both functions return -1 on failure to read a line (including end-of-
file condition). In the event of an error, errno is set to indicate
the cause.
Therefore, you should enhance your code to check for stream errors and deal with errno -- you should do this even when your code works, because EOF is not the only reason for the function
to return -1.
int len = getline(&line, &len, database);
if(len == -1 && ferror(database)) {
perror("Error reading database");
}
You can write more detailed code to deal with errno in more explicit ways.
Unfortunately handling this thoroughly can make your code a bit more verbose -- welcome to C!
#include<stdio.h>
int main()
{
FILE *opening;
opening = fopen("hello.usr","w");
fprintf(opening,"Hello world!");
fclose(opening);
printf("Writing to the file was successful.\n");
printf("Closing the program");
return 0;
}
I have tried this code to create a file in c programming and write the text "Hello world!" in it. What's wrong with this code?
If you want to know what is wrong check the result of fopen
opening = fopen("hello.usr","w");
if (opening == NULL) {
perror("fopen");
}
As of now, you don't know whether you managed to write to the file or not, so here's a suggestion which checks for it.
FILE *opening;
opening = fopen("hello.usr", "w");
if (opening == NULL){
perror("fopen");
return 0;
}
By returning 0 here you remove the option for segmentation fault as the code will still try to write to the file even if it doesn't exist.
The error message you are getting most certainly is NOT produced by a compiler. It looks to me as a message of some automatic checker that tests correctness of the submited solutions.
Make sure that the output matches exactly the required one.
The message:
Your program's output is shorter than the expected
may indicate that there is something wrong with new line characters ('\n'). Check for those.
For example if the required output is:
Writing to the file was successful. Closing the program.
... printed in one line, your output obviously doesn't match as it has a new line after the first sentence. And if the checker testes for the first occurrence of a new line character it sees only
Writing to the file was successful.
which could be one of many possible explanations. If this is the case try simply:
#include<stdio.h>
int main()
{
FILE *opening;
opening = fopen("hello.usr","w");
fprintf(opening,"Hello world!");
fclose(opening);
// printf("Writing to the file was successful.\n");
// printf("Closing the program");
printf("Writing to the file was successful. Closing the program\n");
return 0;
}
Note also that this sort of error messages (in automatic testing environments) are usually triggered by ommited, added extra or confused non-printable characters (spaces, tabs, new lines) or punctuation marks which is hard to notice.
You may also want to check in this respect the text you print to the file.
Try to Instead "w" use "wt" in fopen
Try the following
#include <stdio.h>
int main() {
FILE *opening = fopen("hello.usr", "w");
if(opening == NULL){
printf("An error occurred when opening the file!");
return 0;
}
else{
fprintf(opening, "Hello world!\n");
fclose(opening);
printf("Writing to the file was successful.\nClosing the program.\n");
}
return 0;
}
I am working on a simple C program to open a file and read some data from it. There are no compile errors, but when I run the program on a certain file, I get a "Segmentation Fault: code dumped" error. I inserted a print statement at the very top of my code, and it does not get run. Is it possible to get a segmentation fault when you haven't done anything yet?
#include <stdio.h>
int main(int argc, char **argv)
{
printf("%s", "Made it to here!");
FILE *fp;
char input[100];
fp = fopen(argv[1], "r+b");
fgets(input, sizeof(input), fp);
printf("%s", input);
fclose(fp);
return(0);
}
This works when I run it on the text version of itself, it prints out the first line. However, when I run it on another file, texttest.vmf, I get the segmentation fault and the first print doesn't execute. VMFs are Valve Map Files, but they're in standard text format. This file is about 3.7 KB large. Any ideas?
It is not necessary that your code fails before printf: the call to printf may have succeeded, but because the output to console is buffered, the program may have crashed before the output has been written to the screen.
Adding \n to the output string causes console buffer flush. If you are looking to debug by printfs, you should always add \n to the end of your format string.
Your fopen call is likely failing. Try checking the return value before you attempt to use fp:
FILE *fp;
char input[100];
if((fp = fopen(argv[1], "r+b") == NULL) {
fprintf(stderr, "ERROR: Cannot open file.\n");
return 1;
}
Make sure to add #include <stdlib.h> for use of the NULL macro.