I want to read a number of strings from a text file (standard input) to a 2 dimensional array using getchar(). please ignore the magic number in the code.
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[]) {
char string[100][20];
int c, j = 0, i = 0;
while ((c = getchar()) != EOF) {
while (c != '\n') {
string[j][i] = c;
i++;
}
string[j][i] = '\0';
j++;
}
printf('string is: %s', string);
return 0;
}
you need to use one more getchar() in inner while loop.
while (c != '\n') {
string[j][i] = c;
i++;
c = getchar(); /* this you need here to fetch char until \n encounters */
}
And need to make variable i again 0 once this string[j][i] = '\0'; is done.
Also this
printf('string is: %s', string);
is wrong. It should be
printf("string is: %s", string); /* use double quotation instead of single */
Sample code
int main(int argc, char *argv[]) {
char string[100][20];
int c, j = 0, i = 0;
while ((c = getchar()) != EOF) { /* this loop you need to terminate by pressing CTRL+D(in linux) & CTRL+Z(in windows) */
while (c != '\n') { /* this loop is for 1D array i.e storing char into each 1D array */
string[j][i] = c;
i++;
c = getchar(); /* add this, so that when you press ENTER, inner while loop fails */
}
string[j][i] = '\0';
j++;
i = 0;/* make it zero again, so that it put char into string[j][0] everytime once 1 line is completed */
}
for(int row = 0;row < j;row++) { /* rotate loop j times since string is
2D array */
printf("string is: %s", string[row]);
}
return 0;
}
Related
I am currently learning C and working on a problem that breaks input lines into lengths of n. Below is my current code where n is set to 30. When it reaches the n-th index it replaces that index with ' ' and then line breaks, but it will only do it for the first n characters and I'm unsure what isn't getting rest in order to it to continue making a new line at the nth index.
int getline2(void);
int c, len, cut, counter;
char line[MAXLINE];
main() {
while ((len = getline2()) > 0) {
if (len > BREAK) {
c = 0;
counter = 0;
while (c < len) {
if (line[c] == ' ') {
counter = c;
}
if (counter == BREAK) {
line[counter] = '\n';
counter = 0;
}
counter++;
c++;
}
}
printf("%s", line);
}
return 0;
}
int getline2(void) {
int c, i;
extern char line[];
for (i = 0; i < MAXLINE - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
line[i] = c; //i gets incremented at the end of the loop
if (c == '\n') {
line[i] = c;
++i;
}
line[i] = '\0';
return i;
}
Your code is a little too complicated:
you do not need to store the bytes read from the file into an array, just output them one at a time, keeping track of the line length
when the line would become too long, output a newline and reset the count before you output the byte.
also not that none of these global variables deserves to be global.
and the prototype for main should be either int main(), int main(void) or int main(int argc, char *argv[]) or equivalent. main()` is an obsolete syntax that should be avoided.
Here is a modified version:
#include <stdio.h>
#define BREAK 30
int main() {
int c;
int len = 0;
while ((c = getchar()) != EOF) {
if (c == '\n') {
putchar(c);
len = 0;
} else {
if (len >= BREAK) {
putchar('\n');
len = 0;
}
putchar(c);
len++;
}
}
return 0;
}
I wrote this program that replaces two spaces with an '*'.
How do I modify the code so that it does the same thing regardless of the string size? Is it even possible only using putchar and getchar?
#include <stdio.h>
int c;
char buffer[256];
int counter= 0;
int i;
int main()
{
while ((c = getchar()) != '\n'&&c!=EOF) {
buffer[counter] =c;
counter++;
if (counter >=255) {
break;
}
}
for(i=0; i<256; i++) {
if(buffer[i]== ' '&&buffer[i+1]==' ')
{
buffer[i]= '*';
putchar(buffer[i]);
i = i + 2;
continue;
}
putchar(buffer[i]);
}
putchar('\n');
return 0;
}
The problem statement doesn't require you to store the complete input in a buffer. The decision on what character to output only depends on the last two characters of input. Consider the following code:
#include <stdio.h>
int main(void)
{
// two variables for the last two input characters
int c = EOF, last = EOF;
while ((c = getchar()) != EOF)
{
// if both are a space, store a single '*' instead
if (c == ' ' && last == ' ')
{
c = '*';
last = EOF;
}
// print the output, and shift the buffer
if (last != EOF)
putchar(last);
last = c;
}
// take care of the last character in the buffer after we see EOF
if (last != EOF)
putchar(last);
}
no need for malloc and friends at all. This is a good expample for a problem that requires you to think carefully, before writing code, in order to not waste unnecessary resources on buffers.
Code for just printing:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char prev = EOF, curr;
while ((curr =(char)getchar()) != '\n' && curr != EOF)
{
if(curr==' '&&prev==' ')
{
curr = '*';
prev = EOF;
}
if (prev != EOF)
putchar(prev);
prev = curr;
}
putchar(prev);
return 0;
}
Using realloc for actually changing the string:
#include <stdio.h>
#include <stdlib.h>
int main() {
unsigned int len_max = 128;
char *m = malloc(len_max);
char c;
int counter= 0;
int i;
int current_size = 256;
printf("please input a string\n");
while ((c = getchar()) != '\n' && c != EOF)
{
m[counter] =(char)c;
counter++;
if(counter == current_size)
{
current_size = i+len_max;
m = realloc(m, current_size);
}
}
for(i=0; i<counter; i++)
{
if(m[i]== ' '&&m[i+1]==' ')
{
m[i]= '*';
putchar(m[i]);
i = i + 2;
continue;
}
putchar(m[i]);
}
putchar('\n');
free(m);
m = NULL;
return 0;
}
So my program should get input from an user and store it in an array. After that if the input string includes three 'a's in a row it should be replaced with a single '*'. However I can't seem to get it right. It only replaces the first a with a *. I tried to replace the following 2 a with a blank but the output looks funny.
For this exercise I have to use putchar() and getchar().
Thank you in advance.
#include <stdio.h>
char c;
char buffer[256];
int counter= 0;
int i;
int main()
{
while ((c = getchar()) != '\n') {
buffer[counter] =c;
counter++;
if (counter >255) {
break;
}
}
for(i=0; i<256; i++) {
if(buffer[i]== 'a'&&buffer[i+1]=='a'&&buffer[i+2]=='a')
{
buffer[i]= '*';
buffer[i+1]=' ';
buffer[i+2]=' ';
}
putchar(buffer[i]);
}
putchar('\n');
return 0;
}
So my program should get input from an user and store it in an array.
After that if the input string includes three 'a's in a row it should
be replaced with a single '*'. However I can't seem to get it right.
You almost got it! Just move index by 2 to and continue.
#include <stdio.h>
char c;
char buffer[256];
int counter= 0;
int i;
int main(void)
{
while ((c = getchar()) != '\n') {
buffer[counter] =c;
counter++;
if (counter >= 255) {
break;
}
}
buffer[counter] ='\0';
for(i=0; i<256; i++) {
if(buffer[i]== 'a'&&buffer[i+1]=='a'&&buffer[i+2]=='a')
{
buffer[i]= '*';
putchar(buffer[i]);
i = i + 2;
continue;
}
putchar(buffer[i]);
}
putchar('\n');
return 0;
}
Test:
123aaa456aaa78
123*456*78
In string you must assign a end of character at the end and that is call null character \0 or just a numeric 0. Correct your code like below:-
while ((c = getchar()) != '\n') {
buffer[counter] =c;
counter++;
if (counter >=255) {
break;
}
}
buffer[counter] ='\0';// or buffer[counter] =0;
To avoid side effect in a string array always set all its value with 0 first:-
char buffer[256];
memset(buffer, 0, sizeof(buffer));
If you want to change the number of characters, you will need to create a different buffer to copy the output to.
If you really just want to output to the console, you could just write every character until you hit your matching string.
#include <stdio.h>
char c;
char buffer[256];
char output[256];
int counter= 0;
int i, j;
int main()
{
while ((c = getchar()) != '\n') {
buffer[counter] = c;
counter++;
if (counter >255) {
break;
}
}
buffer[counter] = 0;
for(i=0, j=0; i<256; i++, j++) {
if(buffer[i] == 'a' && buffer[i+1] == 'a'&& buffer[i+2] == 'a')
{
output[j]= '*';
i += 2;
}
else
output[j] = buffer[i];
putchar(output[j]);
}
putchar('\n');
return 0;
}
There are multiple problems in your code:
there is no reason to make all these variables global. Declare them locally in the body of the main function.
use int for the type of c as the return value of getchar() does not fit in a char.
you do not check for EOF.
your test for buffer overflow is off by one.
you do not null terminate the string in buffer. You probably make buffer global so it is initialized to all bits 0, but a better solution is to set the null terminator explicitly after the reading loop.
to replace a sequence of 3 characters with a single one, you need to copy the rest of the string.
You can use a simple method referred as the 2 finger approach: you use 2 different index variables into the same array, one for reading, one for writing.
Here is how it works:
#include <stdio.h>
int main() {
char buffer[256];
int c;
size_t i, j, counter;
for (counter = 0; counter < sizeof(buffer) - 1; counter++) {
if ((c = getchar()) == EOF || c == '\n')
break;
buffer[counter] = c;
}
buffer[counter] = '\0';
for (i = j = 0; i < counter; i++, j++) {
if (buffer[i] == 'a' && buffer[i + 1] == 'a' && buffer[i + 2] == 'a') {
buffer[j] = '*';
i += 2;
} else {
buffer[j] = buffer[i];
}
}
buffer[j] = '\0'; /* set the null terminator, the string may be shorter */
printf("modified string: %s\n", buffer);
return 0;
}
So I want to get all the lines from a file and turn them into a char* array. Problem is that whenever I try to append the character onto the end of the element it gives a segmentation fault.
char** loadOutputs(char *fileName, int *lineCount)
{
FILE *file = fopen(fileName, "r");
if (file) {
char c;
int lines = 0;
while ((c = fgetc(file)) != EOF)
if (c = '\n')
lines++;
rewind(file);
char **output = malloc(lines * sizeof(char*));
for (int i = 0; i < lines; i++)
output[i] = "";
int index = 0;
while ((c = fgetc(file)) != EOF)
if (c == '\n')
index++;
else
strcat(output[i], &c);
return output;
}
return NULL;
}
I always get a segmentation fault at strcat(output[i], &c);. I'd rather not create a fixed array size for the output because this could get fairly large and I don't want to use too much memory.
The following code:
for (int i = 0; i < lines; i++)
output[i] = "";
Is setting the pointer to an empty read only string.
You need to allocate some memory for the string:
I.e.
for (int i = 0; i < lines; i++) {
output[i] = malloc(MAX_LINE_LENGTH + 1);
}
Where MAX_LINE_LENGTH is some defined constant - perhaps #define MAX_LINE_LENGTH 100.
You will need to check that when reading the lines you do not exceed this length.
The following code will do this. This will resolve the other problem in that the address of c will not point to a null terminated string.
int index = 0;
int position = 0;
while ((c = fgetc(file)) != EOF) {
if (c == '\n') {
output[index][position] = 0; // Null terminate the line
position = 0; // Restart next line
index++;
} else {
if (position < MAX_LINE_LENGTH) { // Check if we have space!
output[index][position] = c; // Add character and move forward
position++;
}
}
}
output[index][position] = 0; // Add the null to the final line
Also you need to declare c as and int - i.e. change char c to int c. This is because EOF is outside the range for a char
I'm writing program that counts words in C, I know I can do this simply with fscanf. But I'm using getc.
I have file like this:
One two three four five.
I'm reading chars in while loop and breaking point is when I reach terminal null.
Will c = fgetc(input); or c = getc(input); set c = '\0'; after One_ and after two_ etc.?
When a return value of a function like getc() is EOF which is -1,then you have reached the end of file.try this code to count words:
#include <stdio.h>
int WordCount(FILE *file);
int main(void)
{
FILE *file;
if(fopen_s(&file,"file.txt","r")) {
return 1;
}
int n = WordCount(file);
printf("number of words is %d\n", n);
fclose(file);
return 0;
}
int WordCount(FILE *file)
{
bool init = 0;
int count = 0, c;
while((c = getc(file)) != EOF)
{
if(c != ' ' && c != '\n' && c != '\t') {
init = 1;
}
else {
if(init) {
count++;
init = 0;
}
}
}
if(init)
return (count + 1);
else
return count;
}