I would like to ask, if it is possible to use stdin ended with EOF more than one time. I have something like that:
int ColumnCounter = 0;
int Space = 1;
long IterationCounter = 0;
do
{
while ((Char = getchar()) != EOF)
{
if ((Char != ' ') && (Space == 1))
{
ColumnCounter++;
Space = 0;
}
else if (Char == ' ')
{
Space = 1;
}
else if (Char == '\n' || Char == '\0')
{
putchar('\n');
Space = 0;
ColumnCounter = 1;
continue;
}
if (ColumnCounter == NumberOfCol)
{
putchar(Char);
}
}
ColumnCounter = 0;
Space = 1;
IterationCounter = NumberOfCol++;
IterationCounter++;}
while (IterationCounter < EndingNumberOfCol + 1);
Continue in commentar below.
Yes.Just as you've been doing it almost correctly! Use the following code:
int repeat=0; // Don't forget to initialize repeat
int Znak;
do
{
while ((Znak = getchar()) != EOF)
{ ... }
repeat++; //repeat not reapeat here
}
while (repeat<5); //loop until repeat is less than 5
EDIT: I see you've edited your code.So,Simply implement the above logic into your program.
Related
Using the code below it only reads one char and does not convert morse to letter. My idea was to create a string of one morse "letter" and put it in the convert function, however only 1 char is being read since I am only seeing a single 1 printed on the screen after the string itself is printed. The string only consists of '-' , '.' , ' '. I was wondering if anyone knows what the solution might be.
char convertToLetter(M* data, char word[10]) {
int size = 0;
char correct;
while (size < 60)
{
int compare = strcmp(word, data->morse);
if (compare == 0) {
correct = data->letter;
}
data++;
size++;
}
correct = '\0';
return correct;
}
int main(){
//some code here for opening a file.
char curSent[200];
char letter[6] = "";
int i = 0;
char* fullString = (char*)malloc(1000 * sizeof(char));
fullString[0] = '\0';
while (fgets(curSent, 200, inFile) != NULL) {
if (curSent[0] != '\n') {
curSent[strlen(curSent) - 1] = '\0';
strcat_s(fullString,1000, curSent);
}
else {
printf("%s", fullString);
printf("\n\n");
int j = 0;
while (i < strlen(fullString)) {
if (fullString[i] != ' ') {
fullString[i] = letter[j];
i++;
j++;
printf("%d \n", 1);
}else if (fullString[i + 1] == ' ' && fullString[i] == ' ') {
printf("%d", 2);
printf(" %c", convertToLetter(dictionary, letter));
memset(letter, 0, strlen(letter));
j = 0;
i = i + 2;
}else if (fullString[i] == ' ') {
printf("%d", 3);
printf("%c", convertToLetter(dictionary, letter));
memset(letter, 0, strlen(letter));
j = 0;
i = i++;
}
}
memset(fullString, 0, strlen(fullString));
i = 0;
}
}
//printf("%s", fullString);
getchar();
return 0;
}
I am working on a question which requires me to print a string given a field-number at that position. The strings should be read from a file.
file.txt
C is a language.
lex lexical analyser
(blank line)
gcc is good
If the field-number is 2 (i.e the second word in the sentence). The program should output
is
lexical
(NULL)
is
I wrote a function but don't think its the correct way and that it would work for all cases. It should handle extra blanks or newlines.
while (fgets(buffer, MAX, file) != NULL) {
for (int i = 1; i < strlen(buffer); i++) {
if (count == field_number - 1) {
int j = i;
while (j < strlen(buffer) && buffer[j] != ' ') {
printf("%c", buffer[j++]);
}
printf("\n");
count = 0;
break;
}
if (buffer[i] == ' ' && buffer[i - 1] != ' ') {
count++;
}
}
}
I am a beginner. This code should be easy to understand.
This should work for all the cases,
int main() {
//FILE* file = fopen(__FILE__, "r");
//int field_number = 2;
int new_line = 0; // var to keep track of new line came or not
int word = 0;
int count = 0;
char c, prev_c;
while ((c = fgetc(file)) != EOF) {
// printf("[%c]", c);
// if a new line char comes it means you entered a new line
if(c == '\n') {
// you have to print the new line here on the output to handle
// empty line cases
printf("\n");
new_line = 1; // when line changes
word = 0; // no word has come in this new line so far
count = 0; // count becomes 0
} else if( c == ' ' && prev_c != ' ') {
if(word)
count++;
if(count == field_number) // if count exceeds field_number
new_line = 0; // wait till next line comes
} else if (new_line && count == field_number - 1) {
printf("%c", c);
} else {
word = 1; // fi a not new line or non space char comes, a word has come
}
prev_c = c;
}
return 0;
}
I wrote the following code:
int VALUE = 10;
int counter = 0;
char c;
while (true) {
if(scanf("%c", &c) != 1) {
return NULL;
}
if (c == '\n') {
break;
}
if (counter % VALUE < VALUE - 1) {
num[counter] = c;
counter++;
} else {
char* temp = (char*) malloc((counter + MAX_VALUE)*sizeof(char));
if (temp == NULL) {
return NULL;
}
for (int i = 0; i < counter; i++) {
temp[i] = num[i];
}
free(num);
num = temp;
num[counter] = c;
counter++;
}
}
printf("counter = %d\n",counter);
It doesn't really matter what it does but I have some problem with the counter. For some reason, when I insert 9876.54321 (newline at the end), It does not enters into the if (c == '\n') { break; } block when it scanfs \n, only on the next iteration. The length of 9876.54321 is 10 but it will print 11. What is the reason? I also tried to switch to getchar() but I get the same thing.
Here:
if(scanf("%c", &c) != 1) {
%c in scanf leaves the leading and following whitespace in the input buffer.
To fix this, don't use scanf. Use getchar or getc instead. Instead of using c == '\n', use isspace(c).
Don't do char c. You can't check for EOF if you do that. Instead, use int c.
Full code sample:
int VALUE = 10;
int counter = 0;
int c;
while (true) {
c = getchar();
if (isspace(c) || c == EOF) {
break;
}
if (counter % VALUE < VALUE - 1) {
num[counter] = c;
counter++;
} else {
char* temp = (char*) malloc((counter + MAX_VALUE)*sizeof(char));
if (temp == NULL) {
return NULL;
}
for (int i = 0; i < counter; i++) {
temp[i] = num[i];
}
free(num);
num = temp;
num[counter] = c;
counter++;
}
}
printf("counter = %d\n",counter);
Before reading this question please note that my question pertains to a school assignment. For this assignment the only function we are allowed to use is malloc(). Everything else must be done without the use of other libraries.
I'm calling a function ft_split_whitespaces. This function takes a string as input and "splits" it into words. Words are separated spaces, tabs and line breaks.
#include <stdio.h>
char **ft_split_whitespaces(char *str);
int main(void)
{
char *str = "what is";
char **test = ft_split_whitespaces(str);
}
With respect to the example above the result at each index should be
test[0] = "what"
test[1] = "is"
test[2] = NULL
However, I am only able to print the results of test[0]. All other indices do not get printed to display. Heres an example of some code that I assume should print the results of my function.
int i = 0;
while(test[i] != NULL)
{
printf("%s", test[i]);
i++;
}
When this portion of code is ran, only test[0] is printed to the output. I've been sitting here trying to debug my code for hours. If anyone has some spare time and doesn't mind looking over my code, I'd appreciate it tremendously. I have a feeling it may be an issue with how I'm using malloc, but I still cant figure it out.
#include <stdlib.h>
#include <stdio.h>
int count_whitespaces(char *str)
{
int space_count;
int i;
space_count = 0;
i = 0;
while(str[i] != '\0')
{
if(str[i] == ' ' || str[i] == 9 || str[i] == '\n')
{
if(str[i+1] != ' ' && str[i+1] != 9 && str[i+1] != '\n')
space_count++;
}
i++;
}
return (space_count);
}
int check_whitespace(char c)
{
if (c == ' ' || c == 9 || c == '\n' || c == '\0')
{
return (1);
}
else
return(0);
}
int count_characters(char *str, int i)
{
int char_count;
char_count = 0;
while(str[i])
{
if(str[i+1] != ' ' && str[i+1] != 9 && str[i+1] != '\n')
char_count++;
else
break;
i++;
}
return (char_count);
}
char **ft_split_whitespaces(char *str)
{
int i;
int j;
int k;
char **word;
int space;
i = 0;
j = 0;
k = 0;
word = (char**)malloc(sizeof(char*)*(count_whitespaces(str) + 2));
while(str[i] != '\0')
{
if (check_whitespace(str[i]) == 1)
i++;
else
{
if((word[j] = malloc(sizeof(char) * (count_characters(str, i) + 1))) == NULL)
return (NULL);
while (check_whitespace(str[i]) == 0)
{
word[j][k] = str[i];
i++;
k++;
}
j++;
}
}
j++;
word[j] = NULL;
j = 0
return word;
}
You forgot to reset k. The outer while loop in ft_split_whitespaces should look like that
while (str[i] != '\0') {
if (check_whitespace(str[i]) == 1){
i++;
}
else {
if ((word[j] =
malloc(sizeof(char) * (count_characters(str, i) + 1))) == NULL){
return (NULL);
}
while (check_whitespace(str[i]) == 0) {
word[j][k] = str[i];
i++;
k++;
}
word[j][k] = '\0';
j++;
k = 0; // reset k
}
}
So I actually figured out what was going wrong with my code as I finished typing this question (thanks stack overflow!). I decided to post it anyways, because I thought it might be a good learning experience for coding newbies such as myself.
This is where my issue was occurring.
word = (char**)malloc(sizeof(char*)*(count_whitespaces(str) + 2));
while(str[i] != '\0')
{
if (check_whitespace(str[i]) == 1)
i++;
else
{
if((word[j] = malloc(sizeof(char) * (count_characters(str, i) + 1))) == NULL)
return (NULL);
while (check_whitespace(str[i]) == 0)
{
word[j][k] = str[i];
i++;
k++;
}
j++;
}
}
I malloc'd my char **word outside of the while loop using the following code
word = (char**)malloc(sizeof(char*)*(count_whitespaces(str) + 2));
And then within the actual while loop I malloc'd it again using
word = (char**)malloc(sizeof(char*)*(count_whitespaces(str) + 2));
Using malloc multiple times on the same variable was causing all sorts of weird issues. So within the while loop I ended up using a new variable I declared as char *words. Here is that portion of the while loop with the correct code.
word = (char**)malloc(sizeof(char*)*(count_whitespaces(str) + 2));
while(str[i] != '\0')
{
if (check_whitespace(str[i]) == 1)
i++;
else
{
words = malloc(sizeof(char) * (count_characters(str, i) + 1));
k = 0;
while (check_whitespace(str[i]) == 0)
{
words[k] = str[i];
i++;
k++;
}
words[k] = '\0';
word[j] = words;
j++;
}
}
Here is an outline of what my program is suppose to do so far.
While there are more words in inputLine:
take next word from the inputLine
if next word fits in the inputline2
add the nextword to inputline2 (doesn't work and maybe not needed)
add the inputline2 to outputBuffer (doesn't work)
format outputBuffer
Otherwise:
write the outputBuffer to the output file
empty out the outputBuffer (put \0 in position 0)
No matter what I try though, the outputline2 and/or outputBuffer never copy the contents of the inputline properly. The only reason I have inputline2 is because I was originally using fgets and putting the contents from a line in a text file into inputline. However, since my array length is suppose to be 40, it would always cut some of the words in the original line in half. If this could be avoided somehow I wouldn't even need inputline2. Either way, in both cases, the contents from word (which is just a single word from the original inputline) won't ever copy properly.
void format(FILE *ipf, FILE *outf)
{
char inputline[80];
char outputBuffer[MaxOutputLine];
char word[MaxOutputLine];
while(fgets(inputline, 80, ipf) != NULL)
{
int pos = 0;
int i;
int j = 0;
char inputline2[MaxOutputLine] = {'\0'};
while(pos != -1)
{
i=0;
pos = nextword(inputline, word, pos);
if(strlen(word) <= (40 - strlen(inputline2)))
{
while(i < strlen(word))
{
inputline2[j] = word[i];
i++;
j++;
}
j++;
printf("%s", inputline2);
}
}
}
}
int nextword(char *inputline, char *word, int pos1) //takes a word beginning from pos and puts it in word and re\
turns the new position of beginning of the next word
{
int pos2 = 0;
if(inputline[pos1] == '\0')
{
return -1;
}
if(inputline[pos1] == ' ')
{
while(inputline[pos1] == ' ')
{
pos1++;
}
}
else
{
while(inputline[pos1] != ' ' && inputline[pos1] != '\n' && inputline[pos1] != '\0')
{
word[pos2] = inputline[pos1];
pos1++;
pos2++;
}
if(pos1 == '\n' || pos1 == '\0')
{
return -1;
}
pos1++;
}
word[pos2]='\0';
return pos1;
}
As I can't format a code in comment I send it as answer.
First, I guess your nextword() is similar to:
#include <stdio.h>
#include <string.h>
int nextword(char *inputline, char *word, int pos)
{
char *ptr;
int len;
ptr = strchr(&inputline[pos], ' ');
len = ptr ? ptr - &inputline[pos] : strlen(&inputline[pos]);
strncpy(word, &inputline[pos], len);
word[len] = 0;
if (ptr == NULL)
return -1;
return pos + len + 1;
}
To make clear:
#define MaxOutputLine 40
In format() you have missed the line:
if(strlen(word) <= (40 - strlen(inputline2)))
{
while(i < strlen(word))
{
inputline2[j] = word[i];
i++;
j++;
}
inputline2[j] = ' ';/*missed, otherwise undefined, eg. \0 */
j++;
printf("%s", inputline2);
}
Some compilers have problem with long buffers on stack. You can try to add "static" before char buf[] in format().
In nextword() you have the mistake:
if(pos1 == '\n' || pos1 == '\0')
{
return -1;
}
instead of
if(inputline[pos1] == '\n' || inputline[pos1] == '\0')
{
word[pos2]='\0';
return -1;
}
In my opinion nextword() could be simplified to something like that:
int nextword(char *inputline, char *word, int pos1)
{
int pos2 = 0;
while(inputline[pos1] != ' ' && inputline[pos1] != '\n' && inputline[pos1] != '\0')
{
word[pos2] = inputline[pos1];
pos1++;
pos2++;
}
word[pos2]='\0';
if(inputline[pos1] == '\n' || inputline[pos1] == '\0')
{
return -1;
}
return pos1 + 1;
}