I am trying to build a program that parses an array of chars from input and then returns a formatted omitting extra whites spaces.
#include <stdio.h>
# include <ctype.h>
/* count charecters in input; 1st version */
int main(void)
{
int ch, outp=0;
char str[1000], nstr[1000];
/* collect the data string */
while ((ch = getchar()) != EOF && outp < 1000){
str[outp] = ch;
outp++;
}
for (int j = 0; j < outp-1; j++){
printf("%c",str[j]);
}
printf("\n");
for (int q = 0; q < outp-1; q++)
{
if (isalpha(str[q]) && isspace(str[q+1])){
for(int i = 0; i < outp; i++){
if (isspace(str[i]) && isspace(i+1)){
continue;
}
nstr[i] = str[i];
}
}
}
printf("\n");
printf("Formated Text: ");
for (int i = 0; i < outp-1; i++){
printf("%c", nstr[i]);
}
//putchar("\n");c
// printf("1");
return 0;
}
Here is my code. The array is never fully parsed, the end is usually omitted, odd chars show up and past attempts have yielded a not fully parsed array, Why?
This is exercise 1-9 from "the C programming language".
a) You need to use an additional index variable while copying the characters from str to nstr. Do something like -
for(int i = 0, j = 0; i < outp -1; i++){
if (isspace(str[i]) && isspace(i+1)){
continue;
}
nstr[j++] = str[i];
}
b) While you are printing nstr, you are using the length of the original string str. The length of nstr will be less than that of str since you have removed the spaces.
You need to find the length of nstr now or use i < strlen(nstr) -1 in the condition.
Related
I want to remove all the repeated characters from array. here is example.
"aabccdee"
"bd"
I'm doing this C language. use only array, loop, if,else(conditional statements) not using pointer.
#include<stdio.h>
int main() {
char c[10];
char com[10] = {0,};
char result[10] = { 0, };
int cnt = 0;
for (int i = 0; i < 10; i++) {
scanf("%c", &c[i]);
}
for (int i = 0; i < 10; i++) {
for (int j = i+1; j < 10; j++) {
if (c[i] == c[j]) {
com[i] = c[i];
cnt++;
printf("%c", com[i]);
}
}
}
for (int i = 0; i < cnt; i++) {
for (int j = 0; j < 10; j++) {
if (com[i] != c[j]) {
result[j] = c[j];
}
}
}
printf("\n");
for (int i = 0; i < 10; i++) {
printf("%c", result[i]);
}
}
I thought this
Make repeated array
Compare original array to repeated array
Output
But repeated array loop can't looping all original array.
How can I do remove all repeated character?
Not good SO policy to blatantly answer homework, but I rarely do it and thought this was an interesting task. Certainly making no claims on efficiency, but it looks like it works to me. As far as I can tell, the first and last cases are corner cases, so I handle those individually, and use a loop for everything in the middle. If you're not allowed to use strlen, then you can roll your own or use some other method, that's not the primary focus of this problem (would be best to fgets the string from a command line argument).
#include <stdio.h>
#include <string.h>
int main(void)
{
char source[] = "aabccdee";
char result[sizeof(source)] = { 0 };
unsigned resultIndex = 0;
unsigned i = 0;
// do this to avoid accessing out of bounds of source.
if (strlen(source) > 1)
{
// handle the first case, compare index 0 to index 1. If they're unequal, save
// index 0.
if (source[i] != source[i+1])
{
result[resultIndex++] = source[i];
}
// source[0] has already been checked, increment i to 1.
i++;
// comparing to strlen(source) - 1 because in this loop we are comparing the
// previous and next characters to the current. Looping from 1 to second-to-the-
// last char means we stay in bounds of source
for ( ; i < strlen(source) - 1; i++)
{
if (source[i-1] != source[i] && source[i] != source[i+1])
{
// write to result if curr char != prev char AND curr char != next char
result[resultIndex++] = source[i];
}
}
// handle the end. At this point, i == the last index of the string. Compare to
// previous character. If they're not equal, save the last character.
//
if (source[i] != source[i-1])
{
result[resultIndex] = source[i];
}
}
else if (strlen(source) == 1)
{
// if source is only 1 character, then it's trivial
result[resultIndex] = source[i];
}
else
{
// source has no length
fprintf(stderr, "source has no length.\n");
return -1;
}
// print source and result
printf("source = %s\n", source);
printf("result = %s\n", result);
return 0;
}
Various outputs for source:
source = "aabccdee"
result = "bd"
source = "aaee"
result =
source = "a"
result = "a"
source = "abcde"
result = "abcde"
source = "abcdee"
result = "abcd"
source = "aabcde"
result = "bcde"
source = "aaaaaaaaaaaabdeeeeeeee"
result = "bd"
source = ""
source has no length.
first of all before we speak , you have to check this
you need to put a whitespace when scaning a char using scanf
so
scanf("%c", &c[i]);
becomes
scanf(" %c", &c[i]);
secondly your idea is kinda a messy as the result showed you're only handling cases and it doesn't continue verifying the whole array . you need to learn how to shift an array to the right or left
your issue later on that when you shift your table(not completely) you still print out of the size .
so bascilly in general your code should be something like this :
#include<stdio.h>
int main() {
char c[10];
int length=5;
for (int i = 0; i < 5; i++) {
scanf(" %c", &c[i]);
}
int j,k,i;
for(i=0; i<length; i++)
{
for(j=i+1; j<length; j++)
{
if(c[i] == c[j])
{
length--;
for(k=j; k<length; k++)
{
c[k] = c[k + 1];
}
j--;
}
}
}
printf("\n");
for (int i = 0; i < length; i++) {
printf("%c", c[i]);
}
}
you simply take one case and compare it to the rest , if it exists you shift from the position you find for the second time the element and so on
I am working on a word search assignment for my C class. I need to read in a grid of characters from the console by using the redirection operator such as
./a.out < data1
I am not reading in the data from a file, so I don't need to use file operations. I need to read this grid in and then store it in a 2D array. However, my code just reads in the first line of the grid and stops. Here is my code:
int main(void) {
char inputGrid[50][50];
char solvedGrid[50][50];
char inputString[50];
char ch;
int inputRow = 0;
int rowLength = 0;
int i = 0;
size_t r;
size_t c;
scanf("%[^\n]%*c", inputString);
rowLength = strlen(inputString);
for (r = 0, c = 0; r <= rowLength; r++) {
if (inputString[r] == '\n') {
scanf("%[^\n]%*c", inputString);
inputRow++;
if (inputString[r] != ' ') {
inputGrid[inputRow][c] = inputString[r];
c++;
}
} else
if (inputString[r] != ' ') {
inputGrid[inputRow][c] = inputString[r];
c++;
}
}
// Print the array
for (r = 0; r < strlen(inputString); r++) {
for (c = 0; c < strlen(inputString); c++) {
printf("%c", inputGrid[r][c]);
}
printf("\n");
}
}
I need to read in the data in the form of space separated characters that form a square matrix. Any help would be appreciated.
Each time through the loop, you increment r even though, at most, you have read a single character. You might find it easier to use nested loops: a loop to keep track of the rows/lines, and a loop inside that one to process each character within that row/line.
scanf("%[^\n]%*c", inputString) doesn't store \n in inputString, hence the test inputString[r] == '\n' will never be true.
You could use
int i, r, c;
while (scanf("%[^\n]%*c", inputString) > 0)
{
for (rowLength = i = 0; i < strlen(inputString); ++i)
if (inputString[i] != ' ')
inputGrid[inputRow][rowLength++] = inputString[i];
if (++inputRow >= rowLength) break;
}
// Print the array
for (r = 0; r < inputRow; ++r, printf("\n"))
for (c = 0; c < rowLength; ++c)
printf("%c", inputGrid[r][c]);
I am coding a program which takes a text file as an input, makes the index of the words of it and prints the output(the index) in a file and in the screen. I coded as below and tried much to spot the problem or at least narrow it down, but I couldn't. If anyone can help or spots a problem in syntax or the logic of the code, I would be happy to know.
void main(int argc, char * argv[])
{
//clearscreen
clrscr();
//if arguments are less that default of the program
if (argc < 2)
{
cout << "You should've input 3 arguments." ;
return;
}
//opening the input file and defining a pointer which points to it as argv[1]
FILE *fPtr = fopen(argv[1], "r+");
//defining a 2D array to hold maximum to 200 words holding maximum to 20 characters
char words[200][20];
//initializing words 2D array with zero ASCII
for(int i = 0; i < 200; i++)
for(int j = 0; j < 20; j++)
words[i][j] = 255;
//defining an 2D whi array which is supposed to show how many times words are placed in which lines in a defined layout
//it holds maximum to 200 words holding maximum 100 sentences
int index[200][100];
//initializing the index 2D array with zero ASCII
for(i = 0; i < 200; i++)
for(j = 0; j < 100; j++)
index[i][j] = 0;
//this array of characters max to 2000 is supposed to hold each line which is gotten with fgets
char buff[2000];
//initializing the buff array with zero ASCII
for(i = 0; i < 2000; i++)
buff[i] = 0;
//the max of the words used in the source file is 200. but this valuable named as 'last' says how many words are used in this source file
//its initalized as no words is held
int last = 0;
//defining a pointer to char of punctuation mark characters. all ASCII codes expect for a - z, A - Z, 0 - 9 and newline
char *punc;
//initializing punctuation marks array
for(i = 0; i < 256; i++)
{
if(i == 10)
continue;
if(i >= '0' && i <= '9')
continue;
if(i >= 'a' && i <= 'z')
continue;
if(i >= 'A' && i <= 'Z')
continue;
char *string = (char *) &i;
strncat(punc, string, 1);
}
//how many lines is read from the source file
int lineread = 0;
//a word which the processes are done on that
char *word;
//one line read
while( fgets(buff, 1999, fPtr) != NULL)
{
//how many words is read from the source file in the current line
int wordread = 0;
word = strtok(buff, punc);
//one word read
while( word != NULL)
{
//sorting
int k = 0;
while(strcmp(word, words[k])> 0)
k++;
if(strcmp(word, words[k]))
{
for(int l = last; l >= 0; l--)
{
strcpy(words[l + 1],words[l]);
for(int o = 0; o <= lineread; o++)
index[l + 1][o] = index[l][o];
}
last++;
strcpy(words[k],word);
for(l = 0; l <= lineread; l++)
index[k][l] = 0;
}
index[k][lineread]++;
wordread++;//go to next word
word = strtok(NULL, punc);
}
lineread++;//go to next line
}
//closing the input file
fclose(fPtr);
//opening the output file and defining a pointer which points to it as argv[2]
FILE *fPtr2 = fopen(argv[2], "w+");
//showing the index in cmd
for(i = 0; i <= last; i++)
{
printf("%-20s" , words[i]);
fprinf(fPtr2, "%-20s" , words[i]);
int m = 0;
for(j = 0; j <= lineread; j++)
{
if(m)
{
printf("%c", ',');
fprintf(fPtr2, "%c", ',');
}
if(index[i][j])
{
printf("%i", j + 1);
fprintf(fPtr2, "%i" ,j + 1);
}
if(index[i][j] > 1)
{
printf("(%i)", index[i][j]);
fprintf(fPtr2, "(%i)", index[i][j]);
m = 1;
}
}
printf("\n");
fprintf(fPtr2, "\n");
}
//closing the output file
fclose(fPtr);
}
now it errors as Abnormal program termination NULL pointer assignment. I have to use turbo c and I use DOS SHELL. there's a file names as "input.txt" in resourse. and in DOS SHELL I write this:
programname.exe input.txt output.txt
and my desired output if input.txt is this:
hello. hello.
how are
you? hello.
desired output:
hello 1(2),3 //2 times in line 2, 1 time in line 1
how 2 //1 time in line 2
are 2 //1 time in line 2
you 3 //1 time in line 3
the problem is with this line:
while(strcmp(word, words[k])> 0)
Because index is initialized as 255 and according to the algorithm strcmp works based on, for first word the code works right and puts it in word[0] but for the second word it won't work properly.for example:
first word: Kittens
second word: Biscuits
first strcmp compares Kittens with 255 ASCII code. the result is that Kitten is smaller and the process will put it in word[0]. But for the second word, strcmp compares Biscuits with Kittens and the result is that Kittens is bigger and program will go through another blocks of word[] which in not wanted. the program will be fixed by initializing word[] to 0 and using this code instead of that which is first mentioned:
while(strcmp(word, words[k])> 0)
I have rjecnik.txt file that looks like this
mate sime, jure
stipica gujo, prvi
ante mirkec
goran maja, majica
avion kuca, brod, seoce
amerika, neka, zemlja, krcma
brodarica, zgrada, zagreb
zagreb split
zadar rijeka
andaluzija azija
I need to order lines alphabetically (not words) and my program produces this result which is not correct:
andaluzija azijamate sime, jure
amerika, neka, zemlja, krcma
brodarica, zgrada, zagreb
ante mirkec
avion kuca, brod, seoce
goran maja, majica
stipica gujo, prvi
zadar rijeka
zagreb split
Press [Enter] to close the terminal ...
When I use non ascii character like kuća for kuca or krčma for krcma it produces this result (all wrong)
andaluzija azijamate sime, jure
amerika, neka, zemlja, krŔma
brodarica, zgrada, zagreb
ante mirkec
avion kuŠa, brod, seoce
goran maja, majica
stipica gujo, prvi
zadar rijeka
zagreb split
Press [Enter] to close the terminal ...
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int ch, nl = 1, min, lenght1, lenght2, lenght;//ch will hold characters, min is for selection sort, lenght holds value of strlen for determine wthat line is longer
FILE * fp;// FILE pointer
char * lines[1000];//that will dynamically hold strings for lines
char * temp;//for lines swaping
if((fp = fopen("C:\\Users\\don\\Documents\\NetBeansProjects\\proba2\\dist\\Debug\\MinGW-Windows\\rjecnik.txt", "r")) == NULL)//I had to temporarily put full path to rjecnik.txt
{
printf("Can't open file...");
exit(1);
}
while((ch = getc(fp)) != EOF)//count lines
{
if(ch == '\n')
nl++;
}
int i, j;
for (i = 0; i < nl; i++)
lines[i] = malloc(1000);//create array of string size value of nl
fseek(fp, 0L, SEEK_SET);//go to start of file
i = 0;
j = 0;
while((ch = getc(fp)) != EOF)//fill arrays of string
{
lines[i][j] = ch;
j++;
if(ch == '\n')
{
j = 0;
i++;
}
}
for(i = 0; i < nl - 1; i++)//selection sort doesn't work properly
{
min = i;//min is i
for(j = i + 1; j < nl; j++)//for number of lines(nl) times
{
lenght1 = strlen(lines[i]);//find what string is longer and lenght is smaller one
lenght2 = strlen(lines[j]);
if(lenght1 < lenght2)
lenght = lenght1;
else
lenght = lenght2;
if(strncmp(lines[i], lines[j], lenght) > 0 )//compare two strings
min = j;//if second string is alphabetically smaller min is j
}
temp = lines[i];// swapping
lines[i] = lines[min];
lines[min] = temp;
}
for(i = 0; i < nl; i++ )//printing to console
{
lenght1 = strlen(lines[i]);
for(j = 0; j < lenght1; j++ )
{
putchar(lines[i][j]);
}
}
return 0;
}
Now program crashes at the end when I add this code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int ch, nl = 1, min, lenght1, lenght2, lenght;//ch will hold characters, min is for selection sort, lenght holds value of strlen for determine wthat line is longer
FILE * fp;// FILE pointer
char * lines[1000];//that will dynamically hold strings for lines
char * temp;//for lines swaping
if((fp = fopen("C:\\Users\\don\\Documents\\NetBeansProjects\\proba2\\dist\\Debug\\MinGW-Windows\\rjecnik.txt", "r")) == NULL)//I had to temporarily put full path to rjecnik.txt
{
printf("Can't open file...");
exit(1);
}
while((ch = getc(fp)) != EOF)//count lines
{
if(ch == '\n')
nl++;
}
int i, j;
for (i = 0; i < nl; i++)
lines[i] = malloc(1000);//create array of string size value of nl
fseek(fp, 0L, SEEK_SET);//go to start of file
i = 0;
j = 0;
while((ch = getc(fp)) != EOF)//fill arrays of string
{
lines[i][j] = ch;
j++;
if(ch == '\n')
{
j = 0;
i++;
}
}
for(i = 0; i < nl - 1; i++)//selection sort doesn't work properly
{
min = i;//min is i
for(j = i + 1; j < nl; j++)//for number of lines(nl) times
{
lenght1 = strlen(lines[i]);//find what string is longer and lenght is smaller one
lenght2 = strlen(lines[j]);
if(lenght1 < lenght2)
lenght = lenght1;
else
lenght = lenght2;
if(strncmp(lines[min], lines[j], lenght ) > 0 )//compare two strings
min = j;//if second string is alphabetically smaller min is j
}
temp = lines[i];// swapping
lines[i] = lines[min];
lines[min] = temp;
}
for(i = 0; i < nl; i++ )//printing to console
{
lenght1 = strlen(lines[i]);
for(j = 0; j < lenght1; j++ )
{
putchar(lines[i][j]);
}
}
for (i = 0; i < 100; i++)//Program crashes here
free(lines[i]);
return 0;
}
1.- You must initialize lines to 0 after malloc so strlen works properly.
2.- Compare lines[j] with lines[min]
3.- Don't forget free lines
You're always comparing lines[j] to lines[i], but you should be comparing it to lines[min].
If this isn't you learning about how to sort and get input, c provides qsort() and fgets(), so you could
int strsort(const void *a, const void *b)
{
char *const*astr=a, *const*bstr=b;
return strcmp(*astr, *bstr);
}
main()
{
FILE*f = fopen(...);
char (*arr)[1000] = malloc(1000*1000);
int x;
for(x=0;x<1000 && fgets(1000, arr[x], f);x++)
arr[x][strlen(arr[x])-2] = '\0'; //strip newlines
qsort(arr, x, 1, strsort);
int i;
for(i=0; i<x; i++)
printf("%s\n", arr[x]);
}
It's much clearer what you're doing this way.
Minor nitpick:
lenght1 = strlen(lines[i]);
lenght2 = strlen(lines[j]);
if(lenght1 < lenght2)
lenght = lenght1;
else
lenght = lenght2;
if(strncmp(lines[i], lines[j], lenght) > 0 )
... ;
You don't need this: strcmp() stops when either of the strings terminates, whichever comes first. In your case, you need to compare one more character (the NUL), like
strncmp( lines[i], lines[j], lenght+1)
, otherwise "apple" and "apples" would compare equal (because only the first five characters would be compared). But the "normal" form:
strcmp(lines[i], lines[j])
does exactly what you want.
I'm trying to determine if a phrase is a palindrome (a word that is the same from left to rigth) or not but i can't make it work. What's wrong?, i can't use pointers or recursion or string type variables
#include <stdio.h>
#include <string.h>
int main()
{
int i,j = 0,length;
char space = ' ';
char phrase [80],phrase2[80],phrase3[80];
printf("Give me the phrase: ");
gets(phrase);
length = strlen(phrase);
for(i =0; i <= length - 1; i++)
{
if(phrase[i] != space) //Makes the phrase without spaces
{
phrase2[i] = phrase[i];
j++;
}
}
for(i = length -1; i >= 0;i--)
{
if(phrase[i] != space) //Makes the phrase backwards an without spaces
{
phrase3[j] = phrase[i];
j++;
}
}
length = strlen(phrase2);
for(i =0; i <= length -1;i++) //Compare the phrases to know if they are the same
{
if(phrase2[i] != phrase3[i])
{
printf("It's not a palindrome\n");
return 0;
}
}
printf("It's a palindrome\n");
return 0;
}
Try this:
for(i =0, j=0; i <= length - 1; i++)
{
if(phrase[i] != space) //Makes the phrase without spaces
{
phrase2[j] = phrase[i];
j++;
}
}
for(i = length -1, j = 0; i >= 0;i--)
{
if(phrase[i] != space) //Makes the phrase backwards an without spaces
{
phrase3[j] = phrase[i];
j++;
}
}
length = j;
Update
In response to Praetorian's post here's the code to do it without copying the string.
#include <stdio.h>
#include <string.h>
int main()
{
int i, j, length;
char space = ' ';
char phrase[80];
printf("Give me the phrase: ");
gets(phrase);
length = strlen(phrase);
for( i = 0, j = length - 1; i < j; i++, j-- ) {
while (phrase[i] == space) i++;
while (phrase[j] == space) j--;
if( phrase[i] != phrase[j] ) {
printf("It's not a palindrome\n");
return 0;
}
}
printf("It's a palindrome\n");
return 0;
}
Before the 2nd loop you want to set j=0. It should work after that.
PS: If you debugged by printing out your three strings, you would've figured it out in a matter of minutes. When you don't know what goes wrong, print out the values of variables at intermediate steps, so you know where your problem occurs and what it is.
Your question has already been answered by others but I'm posting this code to show that it is not necessary to make the phrase3 copy to hold the reversed string.
#include <stdio.h>
#include <string.h>
int main()
{
int i, j, length, halfLength;
char space = ' ';
char phrase1[80], phrase2[80];
printf("Give me the phrase: ");
gets(phrase1);
length = strlen(phrase1);
for( i = 0, j = 0; i <= length; ++i ) {
if( phrase1[i] != space ) { //Makes the phrase1 without spaces
phrase2[j++] = phrase1[i];
}
}
length = strlen(phrase2);
halfLength = length / 2;
for( i = 0, j = length - 1; i < halfLength; ++i, --j ) {
if( phrase2[i] != phrase2[j] ) {
printf("It's not a palindrome\n");
return 0;
}
}
printf("It's a palindrome\n");
return 0;
}
This is what I came up with:
#include <stdio.h>
void main() {
char a[50],b[50];
int i=0,j,ele,test=0,x;
while((a[i]=getchar())!='\n') {
if(a[i]!=' ' && a[i]!=',') //do not read whitespaces and commas(for palindromes like "Ah, Satan sees Natasha")
i++;
}
a[i]='\0';
ele=strlen(a);
// Convert string to lower case (like reverse of Ava is avA and they're not equal)
for(i=0; i<ele; i++)
if(a[i]>='A'&&a[i]<='Z')
a[i] = a[i]+('a'-'A');
x = ele-1;
for(j=0; j<ele; j++) {
b[j] = a[x];
x--;
}
for(i=0; i<ele; i++)
if(a[i]==b[i])
test++;
if(test==ele)
printf("You entered a palindrome!");
else
printf("That's not a palindrome!");
}
Probably not the best way for palindromes, but I'm proud I made this on my own took me 1 hour :( lol
Why not use a std::stack? You will need two loops, each iterating the length of the input string. In the first loop, go through the input string once, pushing each character ont the stack. In the second loop, pop a character off the stack and compare it with the character at the index. If you get a mismatch before the loop ends, you don't have a palindrome. The nice thing with this is that you don't have to worry about the even/odd length corner-case. It will just work.
(If you are so inclined, you can use one stack (LIFO) and one queue (FIFO) but that doesn't substantially change the algorithm).
Here's the implementation:
bool palindrome(const char *s)
{
std::stack<char> p; // be sure to #include <stack>
for(int i = 0; s[i] != 0; i++)
p.push(s[i]);
for(int i = 0; s[i] != 0; i++)
{
if(p.top() != s[i])
return false; // not a palindrome!
p.pop();
}
return true;
}
Skipping spaces is left as an exercise to the reader ;)