In C running in Visual Studio Express 2013 on a Windows 7 system, I have the following code which is intended to print out the lines in a text file on which a comment appears. Such lines are indicated in the input file by a # sign as the first character in a line. Assuming a line is:
#George Washington lives here
when I execute the program, it prints out:
comment: α°/
Why isn't my code printing out the line? It has no problem detecting these lines and otherwise processing them.
string str;
ifstream in;
in.open(filename);
if (in.is_open())
getline (in, str);
while (in) {
if (str[0] == '#') { printf("\ncomment: %s", str); }
In Visual Studio 2013 you can configure the character set between Unicode and Multibyte. You can find it in the project propriety.
To "normalize" the string you can add c_str()
printf("\ncomment: %s", str.c_str());
Related
This is the code.
FILE* fPtr;
FILE* fTemp;
char path[100];
char buffer[BUFFER_SIZE];
char newline[BUFFER_SIZE];
int line, count;
printf("Enter path of source file: ");
scanf("%s", path);
printf("Enter line number to replace: ");
scanf("%d", &line);
/* Remove extra new line character from stdin */
fflush(stdin);
printf("Replace '%d' line with: ", line);
scanf("%s", &newline);
/* Open all required files */
fPtr = fopen(path, "r");
fTemp = fopen("replace.tmp", "w");
/* fopen() return NULL if unable to open file in given mode. */
if (!fPtr)
{
/* Unable to open file hence exit */
printf("\nUnable to open file.\n");
printf("Please check whether file exists and you have read/write privilege.\n");
exit(EXIT_SUCCESS);
}
/*
* Read line from source file and write to destination
* file after replacing given line.
*/
count = 0;
while ((fgets(buffer, BUFFER_SIZE, fPtr)) != 0)
{
count++;
/* If current line is line to replace */
if (count == line)
fputs(newline, fTemp);
else
fputs(buffer, fTemp);
}
/* Close all files to release resource */
fclose(fPtr);
fclose(fTemp);
/* Delete original source file */
remove(path);
/* Rename temporary file as original file */
rename("replace.tmp", path);
printf("\nSuccessfully replaced '%d' line with '%s'.", line, newline);
return 0;
I wanted to replace a line supposedly the content of the text file is this
> Andy,06/05/2000,US,0654852,254845,313132
> Fan,865644,4654654,654654,465456
> Ben,04/01/1995,SG,0674874,213454,132158
Supposedly I wanted to change the of Fan so I run the code above, it gave me this. I do not want this to happen.
> Andy,06/05/2000,US,0654852,254845,313132
> Fanny,865644,4654654,654654,465456Ben,04/01/1995,SG,0674874,213454,132158
And if I want to change the name of Andy it gave me this
Landy,06/05/2000,US,0654852,254845,313132Fanny,865644,4654654,654654,465456Ben,04/01/1995,SG,0674874,213454,13215
Why it does that?
How do I delete specific line and replace it ?
Assume that the replacement line has a different size than the original one. You cannot do that in standard C11 (check n1570) without copying the file to a new place (because you cannot overwrite a sequence of bytes in the middle of a file by another sequence of different length).
Read carefully the documentation of <stdio.h>
Lines are just a convention in C: they are ending by some end-of-line character (\n). A file could have a single line and contain a megabyte.
So you could use getline to read lines. Or use fgets. In both cases you should check for failure. With fgets what would happen if the line is bigger than the buffer? With getline what would happen with a file containing a single line of a gigabyte which does not fit into memory?
Be aware that stdout is buffered (and the buffer size could vary from one run to the next one and could be different if you use command pipelines). See setvbuf and fflush. In practice, take the habit of ending your printf format control string with \n and/or explicitly calling fflush
Many open source programs doing what you want already exist. GNU ed comes to mind. Consider studying its source code for inspiration.
Please read how to debug small programs. If you use a recent GCC compiler with some GDB debugger, compile with all warnings and debug info, so gcc -Wall -Wextra -g then use gdb to understand the behavior of your program. Specify on paper the input file syntax using EBNF and read more about parsing techniques, including recursive descent parsing.
Notice that:
fflush(stdin);
is undefined behavior. You should fflush output streams only.
PS. You could later read about databases then consider using sqlite.
fgets will read from the file up to and including the newline character at the end of the line. The scanf call you use to get the replacement string does not, so when you write out newline it does not contain a newline character.
Solutions include explicitly adding the newline (possibly with fputc('\n', fTemp);, or using fgets(newline, BUFFER_SIZE, stdin); instead of the scanf to read your input string.
Yes I want to use
fgets(new,line,buffer_sizze,stdin);
but it just won't ask for input unless I put it inside of main().
When I put it inside of a function that I created, it won't ask for input from the user which is why I used scanf.
Is there a way to put it \n without asking the user to type \n.
Or any solution to why it's not getting input when I used fgets.
For the people that has the same problem as me.
Fgets not asking for any input.
Try use getchar().
That solved my problem.
For unknown reason.
This question already has answers here:
Simple program adding "D" to output
(3 answers)
Why does C program print 0D instead of 0? (When EOF sent as Ctrl+D) [duplicate]
(1 answer)
Closed 5 years ago.
I was coding a very simple programme to detect word pattern by entering to stdin and return the times found the pattern.
However the code return me the correct number but follow a char D.
#include <stdio.h>
#include "string.h"
#define MAXLINE 1000 /* maximum input line length */
char pattern[] = "ould"; /* pattern to search for */
/* print all lines from standard input that match pattern */
int main()
{
char line[MAXLINE];
int found = 0;
while (fgets(line, MAXLINE, stdin) != NULL)
if (strstr(line, pattern) != NULL) {
printf("%s", line);
found++;
}
printf("%d \n", found);
return 0;
}
Result:
glaroam2-180-76:Lab2 apple$ ./find0
fould
fould
1D
The code is correct (apart from the #include "string.h" which should be
#include <string.h>)1, the problem is that when you press
Ctrl+D on your terminal, your terminal might write
something on the terminal, which you cannot control and this output might be
^D
After fgets returns NULL, you do printf("%d \n", found); which prints the '1'.
But because there was ^D on the terminal, the ^ was replaced by the '1' and
you end up with:
1D
Change your last printf to this:
printf("\n\n%d \n, found);
And you might see only a '1' in the next lines of the output.
This has nothing to do with your C program, it's the behaviour of your terminal.
My terminal for example doesn't print when pressing Ctrl+D,
but when pressing Ctrl+C I get ^C. There's nothing you
can do.
edit
With There's nothing you can do I mean that you cannot control the way the
terminal from you C program without calling external tools like stty. While
this might solve your problem, you are loosing portability.
However, before you start you program, you can configure your terminal using a
program like stty. See Jonathan Leffler's answer for more info on that.
Fotenotes
1As Jonathan Leffler points out in the comments, using quotes instead
of angle brackets for system headers is not an error per se. For example my GCC
compiler searches in the same directory of the compiled file for headers that
were included with quotes. But in general, it's a good practice to include the
header files included provided by your system with angle brackets.
It's a terminal setting: echoctl. It means that when you type Control-D, the terminal echoes ^D, and then the 1 overwrites the ^. Try using:
stty -echoctl
and then rerunning your program.
With that said, I'm surprised that the D isn't wiped out by the blank after the %d in the format string. I suspect your actual code may be missing that. When I tested on my Mac, the program with the space after the %d did not show the D for long enough for me to spot it; when I removed that space, I got the output shown in the question.
While Trying this code on eclipse CDT with GCC 5.1.0 Compiler
All the strings were printed after the user input ..
and while compiling it on Visual Studio and Code Blocks IDEs even with the windows CMD The program worked just fine as expected ..
#include <stdio.h>
static char string[128] = "";
int main() {
printf("Type a string: ");
scanf("%s",string);
printf("The String is %s", string);
return 0;
}
Eclipse Output:
Visual Studio Output:
Thanks ,,,
OK, I see now. I think the issue is that whenever you want to be certain that something is printed by a given point in the code, you need to flush stdout at that point.
Otherwise, streamed contents can be queued and delivered in an implementation-dependent way (usually in small batches)
The C standard library's printf(), when outputting to stdout and encountering a newline \n, provides an implicit flush, so you don't need to call flush() yourself. Whereas with C++'s std::cout, only std::endl has this property; \n is not guaranteed to.
Deliberately flushing stdout in C can be done like so: fflush(stdout);
See also: Why does printf not flush after the call unless a newline is in the format string?
Ok so i am writing a C program. The program is simple enough, when i run the program i give it a few parameter Ex ./proj1 cat hat bat, so then it asks me to input a list of words the program gives counts of how many times "cat", "hat", and "bat" occurs in that list.
I have the program working great.
Example
./pro1 cat hat bat
cat
.
(the program recognized a "." as the end of input)
Result:
cat:1
hat:0
bat:0
ok so my program runs perfectly in every test case i can think of, but I have to pass a series of tests that my professor has mas made.
here is the code of that test.
char *args[] = {"./main", "cat", "hat","bat",NULL};
char *result[] = {"Looking for 3 words\n",
"Result:\n",
"cat:1\n",
"hat:0\n",
"bat:0\n"};
FILE *out;
FILE *test;
test=fopen("test","w");
int i;
char *buffer=malloc(100*sizeof(char));
out = fopen("smp0.in", "w");
fprintf(out, "cat\n");
fprintf(out, ".\n");
fclose(out);
freopen("smp0.in", "r", stdin);
freopen("smp0.out", "w", stdout);
quit_if(main(4, args) != EXIT_SUCCESS);
fclose(stdin);
fclose(stdout);
out = fopen("smp0.out", "r");
for (i = 0; i < 5; i++) {
quit_if(fgets(buffer, 100, out) == NULL);
quit_if(strcmp(buffer, result[i]));
}
fclose(out);
return EXIT_SUCCESS;
}
ok so sending the quit_if() is the method that makes it fail. specifically
quit_if(strcmp(buffer, result[i]));
My output when i run the program is exactly as described. But between freopen() diverting stdout to a file and then reading it back it has changed somehow.
Result:
cat:1
hat:0
batÿ:0
is what the output becomes, but it is not like that before the file write and read, and for some reason it is always that weird y character.
any advice would be greatly appreciated.
Sorry for not posting more code but it's because it is a school project.
I am confident that it is the test that is wrong in some way and not my code, fixing the test is part of the project as well.
See this answer to a previous question:
https://stackoverflow.com/a/4906442/2009431
It seems that when the dot is read back in from your stdin file, it has an EOF token appended (makes sense) that would not normally be part of the user's input. Then, somehow (not sure since we can't see your code) your main() function is appending that EOF character onto "bat" in the form of that weird y character (see linked answer for details on why).
If I'm right, maybe this could be considered a bug in the test?
A friend of mine needs to use MATLAB for one of his classes, so he called me up (a Computer Science Major) and asked if I could teach him C. I am familiar with C++, so I am also familiar with the general syntax, but had to read up on the IO library for C.
I was creating some simple IO programs to show my friend, but my third program is causing me trouble. When I run the program on my machine using Eclipse (with the CDT) Eclipse's console produces a glitchy output where instead of prompting me for the data, it gets the input and then prints it all at once with FAILURE.
The program is supposed to get a filename from user, create the file, and write to it until the user enters a blank line.
When I compile/run it on my machine via console (g++ files2.c) I am prompted for the data properly, but FAILURE shows up, and there is no output file.
I think the error lies with how I am using the char arrays, since using scanf to get the filename will create a functional file (probably since it ignores whitespace), but not enter the while loop.
#include <stdio.h>
#define name_length 20
#define line_size 80
int main() {
FILE * write_file; // pointer to file you will write to
char filename[name_length]; // variable to hold the name of file
char string_buffer[line_size]; // buffer to hold your text
printf("Filename: "); // prompt for filename
fgets(filename, name_length, stdin); // get filename from user
if (filename[name_length-1] == '\n') // if last char in stream is newline,
{filename[name_length-1] = '\0';} // remove it
write_file = fopen(filename, "w"); // create/overwrite file user named
if (!write_file) {printf("FAILURE");} // failed to create FILE *
// inform user how to exit
printf("To exit, enter a blank line (no spaces)\n");
// while getting input, print to file
while (fgets(string_buffer, line_size, stdin) != NULL) {
fputs(string_buffer, write_file);
if (string_buffer[0] == '\n') {break;}
}
fclose(write_file);
return 0;
}
How should I go about fixing the program? I have found next to nothing on user-terminated input being written to file.
Now if you will excuse me, I have a couple of files to delete off of my University's UNIX server, and I cannot specify them by name since they were created with convoluted filenames...
EDIT------
Like I said, I was able to use
scanf("%s", filename);
to get a working filename (without the newline char). But regardless of if I use scanf or fgets for my while loop, if I use them in conjunction with scanf for the filename, I am not able to write anything to file, as it does not enter the while loop.
How should I restructure my writing to file and my while loop?
Your check for the newline is wrong; you're looking at the last character in filename but it may be before that if the user enters a filename that's shorter than the maximum. You're then trying to open a file that has a newline in it's name.
These lines seem to be incorrect:
if (filename[name_length-1] == '\n') // if last char in stream is newline,
{filename[name_length-1] = '\0';} // remove it
You verify the name_length - 1 character,, which is 19 in your case without any regard of the introduced filename's length. So if your file name's length is less then 18 you won't replace the '\n' character at the end of your string. Obviously the file name can't contain '\n' character.
You need to get the size of you file name first with strlen() as an example.
if (filename[strlen(filename) - 1] == '\n')
{
filename[strlen(filename) - 1] = '\0';
}
(Don't forget to include the string.h header)
I hope I was able to help with my weak english.