I need a program to reverse the order of all strings stored in one or more text files. This is what i've got so far:
#include <stdio.h>
main(int argc, char *argv[])
{
int i;
for (i=1;i < argc;i++)
{
FILE *MyFile=fopen(argv[i], "r");
int i,len;
char str[1000], *ptr;
fgets(str, 1000, MyFile);
ptr = str;
for(i=0;i<1000;i++)
{
if(*ptr == '\0') break;
ptr++;
}
len = i;
ptr--;
for(i=len; i>0; i--)
{
printf("%c",*ptr--);
}
printf("\n");
fclose (MyFile);
}
return 0;
}
What i'm not being able to do is to loop the program correctly so that it reverses all strings. Currently it reverses the first string of all files, but when it encounters a line break the fgets stops. What i've tried to do is to count the lines in the current file, do a for loop, and at the end do another fgets(str, 1000, MyFile); to advance the fgets, but I somehow manage to mess things up.
Another option I thought of is to create a separate function which only reverses a given string, and inside the main function call that function the appropriate number of times, but i'm not sure how to handle the argc and *argv[] in this situation.
Any help? Thanks!
You are clobbering the i variable for the outer loop with another one declared inside. This is most probably why it doesn't work.
You should use strlen() function to get the string length instead of calculating it manually.
Unless you are guaranteed to have strings of at most 1000 bytes, you should consider using a smarter algorithm to cater for longer strings.
Accumulate each char in a buffer until end-of-string (\0) detected. Then print it in reverse.
printf_reverse(const char *buf, size_t len) {
while (len > 0) {
fputc(buf[--len], stdout);
}
}
char buf[1000];
size_t len = 0;
int ch;
while ((ch == fgetc(MyFile)) != EOF) {
if (ch == '\0') {
printf_reverse(buf, len);
len = 0;
}
// You may want not use EOL as part of the reverse
else if (ch == '\n') {
printf_reverse(buf, len);
fputc(ch, stdout);
len = 0;
}
else if (len < sizeof(buf)) {
buf[len++] = ch;
}
else {
; // handle error string too long
}
printf_reverse(buf, len);
OP says "ABCD 1234 Should output: DCBA 4321". In C, a string ends with a \0. It is not clear if the source file has embedded \0 or OP also wants to use a space to indicate the end of the string.
Related
I am new to C and am getting very frustrated with learning this language. Currently I'm trying to write a program that reads in a program textfile, reads and prints all the string literals, and tokens each on separate line. I have most of it except for one snag. within the text file there is a line such as: (..text..). I need to be able to search, read and print all the text is inside the parentheses on it's own line. Here is an idea I have so far:
#define KEY 32
#define BUFFER_SIZE 500
FILE *fp, *fp2;
int main()
{
char ch, buffer[BUFFER_SIZE], operators[] = "+-*%=", separators[] = "(){}[]<>,";
char *pus;
char source[200 + 1];
int i, j = 0, k = 0;
char *words = NULL, *word = NULL, c;
fp = fopen("main.txt", "r");
fp2 = fopen ("mynewfile.txt","w") ;
while ((ch = fgetc(fp)) != EOF)
{
// pus[k++] = ch;
if( ch == '(')
{
for ( k = 0;, k < 20, K++){
buffer[k] = ch;
buffer[k] = '\0';
}
printf("%s\n", buffer)
}
....
The textfile is this:
#include <stdio.h>
int main(int argc, char **argv)
{
for (int i = 0; i < argc; ++i)
{
printf("argv[%d]: %s\n", i, argv[i]);
}
}
So far I've been able to read char by char and place it into a buffer. But this idea just isn't working, and I'm stumped. I've tried dabbling with strcopy(), ands strtok, but they all take char arrays. Any ideas would be appreciated thank you.
Most likely the best way would be to use fgets() with a file to read in each line as a string (char array) and then delimit that string. See the short example below:
char buffer[BUFFER_SIZE];
int current_line = 0;
//Continually read in lines until nothing is left...
while(fgets(buffer, BUFFER_SIZE - 1, fp) != NULL)
{
//Line from file is now in buffer. We can delimit it.
char copy[BUFFER_SIZE];
//Copy as strtok will overwrite a string.
strcpy(copy, buffer);
printf("Line: %d - %s", current_line, buffer); //Print the line.
char * found = strtok(copy, separators); //Will delmit based on the separators.
while(found != NULL)
{
printf("%s", found);
found = strtok(NULL, separators);
}
current_line++;
}
strtok will return a char pointer to where the first occurrence of a delimiter is. It will replace the delimiter with the null terminator, thereby making "new" string. We can pass NULL to strtok to tell it to continue where it left off. Using this, we can parse line by line from a file based on multiple delimiters. You could save these individual string or evaluate them further.
I want to create a program in C that takes an arbitrary number of lines of arbitrary length as input and then prints to console the last line that was inputted. For example:
input:
hi
my name is
david
output: david
I figured the best way to do this would be to have a loop that takes each line as input and stores it in a char array, so at the end of the loop the last line ends up being what is stored in the char array and we can just print that.
I have only had one lecture in C so far so I think I just keep setting things up wrong with my Java/C++ mindset since I have more experience in those languages.
Here is what I have so far but I know that it's nowhere near correct:
#include <stdio.h>
int main()
{
printf("Enter some lines of strings: \n");
char line[50];
for(int i = 0; i < 10; i++){
line = getline(); //I know this is inproper syntax but I want to do something like this
}
printf("%s",line);
}
I also have i < 10 in the loop because I don't know how to find the total number of lines in the input which, would be the proper amount of times to loop this. Also, the input is being put in all at once from the
./program < test.txt
command in Unix shell, where test.txt has the input.
Use fgets():
while (fgets(line, sizeof line, stdin)) {
// don't need to do anything here
}
printf("%s", line);
You don't need a limit on the number of iterations. At the end of the file, fgets() returns NULL and doesn't modify the buffer, so line will still hold the last line that was read.
I'm assuming you know the maximum length of the input line.
This one here will surely do the job for you
static char *getLine( char * const b , size_t bsz ) {
return fgets(b, bsz, stdin) );
}
But remember fgets also puts a '\n' character at the end of buffer so perhaps something like this
static char *getLine( char * const b , size_t bsz ) {
if( fgets(b, bsz, stdin) ){
/* Optional code to strip NextLine */
size_t size = strlen(b);
if( size > 0 && b[size-1] == '\n' ) {
b[--size] = '\0';
}
/* End of Optional Code */
return b;
}
return NULL;
}
and your code needs to be altered a bit while calling the getline
#define BUF_SIZE 256
char line[BUF_SIZE];
for(int i = 0; i < 10; i++){
if( getLine(line, BUF_SIZE ) ) {
fprintf(stdout, "line : '%s'\n", line);
}
}
Now it is how ever quite possible to create function like
char *getLine();
but then one needs to define the behavior of that function for instance if the function getLine() allocates memory dynamically then you probably need use a free to de-allocate the pointer returned by getLine()
in which case the function may look like
char *getLine( size_t bsz ) {
char *b = malloc( bsz );
if( b && fgets(b, bsz, stdin) ){
return b;
}
return NULL;
}
depending on how small your function is you can entertain thoughts about making it inline perhaps that's a little off topic for now.
In order to have dynamic number of input of dynamic length, you have to keep on reallocating your buffer when the input is of greater length. In order to store the last line, you have to take another pointer to keep track of it and to stop the input from the terminal you have to press EOF key(ctrl+k). This should do your job.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *get_last_line(FILE* fp, size_t size){
//The size is extended by the input with the value of the provisional
char *str, *last_str = NULL;
int ch;
size_t len = 0, last_len = 0;
str = realloc(NULL, sizeof(char)*size);//size is start size
if(!str)return str;
while(ch=fgetc(fp)){
if(ch == EOF){
break;
}
if(ch == '\n'){
str[len]='\0';
last_len = len;
last_str = realloc(last_str,sizeof(char)*last_len);
last_str[last_len]='\0';
//storing the last line
memcpy(last_str,str,sizeof(char)*last_len);
str = realloc(NULL, sizeof(char)*size);//size is start size
len = 0;
}
else {
str[len++]=ch;
if(len==size){
str = realloc(str, sizeof(char)*(size+=16));
if(!str)return str;
}
}
}
free(str);
return last_str;
}
int main(void){
char *m;
printf("input strings : ");
m = get_last_line(stdin, 10);
printf("last string :");
printf("%s\n", m);
free(m);
return 0;
}
I need a simple function that can read multiple words into a string in C, kind of like Scanner.nextLine() in Java or Console.ReadLine() in C#, but I can't seem to find a simple method anywhere, I tried all sorts of things, but none of them seem to work 100% of the time.
You can use fgets
char *fgets(char *str, int n, FILE *stream)
Be aware that fgets reads until reach the size n, or a newline or an EOF.
This is made to avoid buffer overflow, so you need to make sure that your buffer is big enough to store the string.
scanf is what you want:
#include <stdio.h>
int main(void)
{
char string[50];
scanf(" %49[^\n]s",string);
printf("you entered: %s\n",string);
}
you can follow this:
char str[100];// as length of the total words neded
fgets(str,100,stdin)
printf("output: %s",str);
return 0;
Use fgets to parse an input string into a char buffer.
char * fgets ( char * str, int num, FILE * stream );
Here is the link for a better description
Then use sscanf to dissect this string to however you need it.
int sscanf ( const char * s, const char * format, ...);
Here is the link for a better description
This removes the '\n' character that is included in the string returned by fgets, thus making the function practically equivalent to the functions present in popular managed languages:
//gets a line from the specified stream
int getline(char* charArray, int maxLength, FILE* stream) {
int i;
if (fgets(charArray, maxLength, stream) == NULL)
return 1; //some error occurred
for (i = 0; i < maxLength; i++) {
if (charArray[i] == '\n') {
if (i != 0 && charArray[i - 1] == '\r') //cater for windows line endings
i--;
charArray[i] = '\0';
return 0; //all's well that ends well
} else if (charArray[i] == '\0')
return 0; //smooth sailing fam
}
return 2; //there was no string terminator
}
Here you go:
#include "stdio.h"
//gets a line from the specified stream
int getline(char* charArray, int maxLength, FILE* stream) {
int i;
if (fgets(charArray, maxLength, stream) == NULL)
return 1; //some error occurred
for (i = 0; i < maxLength; i++) {
if (charArray[i] == '\n') {
if (i != 0 && charArray[i - 1] == '\r') //cater for windows line endings
i--;
charArray[i] = '\0';
return 0; //all's well that ends well
} else if (charArray[i] == '\0')
return 0; //smooth sailing fam
}
return 2; //there was no string terminator
}
int main() {
char money[4];
printf("How much money do you have on you? ");
getline(money, 4, stdin);
printf("Oh really? $%d? Good. :)\n", atoi(money));
char string[4];
printf("Where is our next lesson?\n");
getline(string, 4, stdin);
printf("%s", string);
return 0;
}
I am working on a program that should remove preceding spaces and tabs from each line of text in a given file (case b). I read the file from stdin, which I got working fine. However I am getting a nasty seg fault that I can't figure out. It happens when I call strcat() in case b. Basically what I was trying to do in case b is iterate through each line (80 characters) in the text file, remove any preceding tabs or spaces from the line, then put these lines back into finalText. Can anyone see where am I going wrong? Or if there might be a simpler approach?
Here's my code:
int main(int argc, char* argv[]) {
int x = 0;
int i = 0;
int j = 0;
int y = 0;
int count = 1;
char *text = malloc(sizeof(char) * 1024);
char *finalText = malloc(sizeof(char) * 1024);
char buff[80];
while(fgets(buff, 80, stdin) != NULL){
strcat(text, buff);
}
while ((x = getopt(argc, argv, "bic:")) != -1){
switch (x){
case 'b':
for(; text[i] != EOF; i += 80){
char buff2[80];
char *buff3;
j = i;
y = 0;
while(j != (80 * count)){
buff2[y] = text[j];
y++;
j++;
}
buff3 = buff2;
while(*buff3 && isspace(*buff3)){
++buff3;
}
count++;
strcat(finalText, buff3);
}
printf(finalText);
break;
default:
break;
}
}
return 0;
}
#include <stdio.h>
int main(){
char buff[80];
int n;
while(fgets(buff, sizeof(buff), stdin)){
sscanf(buff, " %n", &n);
if(n && buff[n-1] == '\n')//only whitespaces line.(nothing first word)
//putchar('\n');//output a newline.
fputs(buff, stdout);//output as itself .
else
fputs(buff + n, stdout);
}
return 0;
}
Firstly before the 'b' case, there is another problem too. You have allocated 1024 byte for text. Each line you read from stdin is concatenated at text string. If the total characters read from stdin exceed 1024 bytes you will receive a segmentation fault.
For your problem at 'b' case:
Why searching for EOF? EOF is not a character and your loop will continue to iterating incrementing i until you receive a segmentation fault. You just want to iterate until the end of the string which can be retrieved with strlen() for example.
I have a homework problem that I need help with. I need to implement a function char *getStrFromFile(FILE*);. I just simply don't understand it. I have attempted to figure out the question.
This function safely reads a complete line of unknown length from the
open file pointed to by fpin. It returns a line that is at most CHUNKSZ-1
characters longer than the minimum needed to hold the line.
It initially allocates an array of DEFLEN characters to hold the string,
and if this space is inadequate to hold the string, it will iteratively
create a new string that is CHUNKSZ larger, copy the old string to it
release the old string, and then read in more characters from the file,
and continue this until the entire line of arbitrary length can be returned.
RETURNS: NULL if no characters are left in fpin, otherwise:
pointer to allocated array at most CHUNKSZ-1 characters longer than
miminum necessary to hold an arbitrarily long line from file fpin
int main(int nargs, char *args[])
{
FILE *fpin;
char *getStrFromFile(FILE*);
if (nargs != 2)
{
fprintf(stderr, "USAGE: %s <file>\n", args[0]);
exit(1);
}
fpin = fopen(args[1], "r");
while(1)
{
char *ln;
ln = getStrFromFile(fpin);
if (!ln)
break;
printf("%s", ln);
free(ln);
}
fclose(fpin);
return(0);
}
That is the main method I have to use. Here is what I know so far.
char *getStrFromFile(FILE *fpin)
{
char string[DEFLEN];
if(fgets(string, CHUNKSZ, fpin) != NULL) {
int l = lstr(string);
if(string[l-1] = '\n') {
return string;
} else {
int size = 1;
int end = 0;
while (string[l-1] != '\n') {
size += CHUNSZ;
char *s2 = (char*)malloc(sizeof(char)+size);
for(i = 0+end; i < lstr(string); i++) {
s2[i] = string[i];
}
end += lstr(string);
fgets(string, size + end, fpin);
return s2;
This is not correct.
if(string[l-1] = '\n')
it must be
if(string[l-1] == '\n')