This question already has answers here:
Can array length in declaration be non-constant?
(3 answers)
Closed 2 years ago.
does char myStr[varLength] work in C?
I have the following (code here):
int isVMin(char c){
return c == 'a' ||
c == 'e' ||
c == 'i' ||
c == 'o' ||
c == 'u' ||
c == 'y';
}
int isNum(char c){
return c>='0' && c<='9';
}
int removeChars(char str[]){ // removes all vowels, returns the digits number
int slen = strlen(str);
//char* res = malloc(sizeof(char)*slen+1);
char res[slen + 1]; /// <<<<<<<<<<<<<<<<<<<<<<<<<<<<< DOES IT WORK AS EXPECTED???
printf("\nthe initial is: '%s'\n", res);
int numCount = 0, j = 0;
for (int i = 0; i < slen; i++) {
if (isVMin(str[i]));
//str[i]= ' ';
else {
res[j++] = str[i];
if (isNum(str[i]))
numCount++;
}
}
res[j] = '\0';
printf("\nthe removed is: '%s'\n", res);
//str = res;
return numCount;
}
int main(){
char phrase[50];
gets(phrase);
int nb = removeChars(phrase);
printf("\nLa phrase '%s' contient %d digits", phrase, nb);
return 0;
}
The program compiles and work as expected. However I have doubts if this usage is legal in C...
char res[slen + 1]; /// <<<<<<<<<<<<<<<<<<<<<<<<<<<<< DOES IT WORK AS EXPECTED???
This works starting in C '99.
You're kind of limited as to how big. A rule of thumb would be exceeding 8k is probably not recommended. Note that on Windows, if the whole stack exceeds 1mb, the program will crash. On modern Unix. the same thing happens at a larger limit.
You can't return it though. Just sayin'
Related
this program checks weather the entered string is palindrome or not . it should be in a way like it should even tell the string is palindrome if there is space or any special character
like messi is a palindrome of iss em
and ronald!o is a palindrome of odlanor
this is the program and for some odd reason it is strucking and not working
#include <stdio.h>
#include <string.h>
int main() {
char palstr[100], ans[100];
printf("enter the string for checking weather the string is a palindrome or not");
scanf("%[^/n]", &palstr);
int ispalin = 1, i = 0, n = 0;
int num = strlen(palstr);
printf("the total length of the string is %d", num);
while (i <= num) {
if (palstr[i] == ' ' || palstr[i] == ',' || palstr[i] == '.' ||
palstr[i] == '!' || palstr[i] == '?') {
i++;
}
palstr[n++] == palstr[i++];
}
int j = num;
i = 0;
while (i <= num) {
ans[j--] = palstr[i];
}
printf("the reverse of the string %s is %s", palstr, ans);
if (ans == palstr)
printf("the string is a palindrome");
else
printf("the string is not a palindrome");
return 0;
}
A few points to consider. First, regarding the code:
if (ans == palstr)
This is not how you compare strings in C, it compares the addresses of the strings, which are always different in this case.
The correct way to compare strings is:
if (strcmp(ans, palstr) == 0)
Second, you should work out the length of the string after you have removed all unwanted characters since that's the length you'll be working with. By that I mean something like:
char *src = palstr, dst = palstr;
while (*src != '\0') {
if (*c != ' ' && *src != ',' && *src != '.' && *src != '!' && *src != '?') {
*dst++ = *src;
}
src++;
}
Third, you have a bug in your while loop anyway in that, if you get two consecutive bad characters, you will only remove the first (since your if does that then blindly copies the next character regardless).
Fourth, you may want to consider just stripping out all non-alpha characters rather than that small selection:
#include <ctype.h>
if (! isalpha(*src) {
*dst++ = *src;
}
Fifth and finally, you don't really need to create a new string to check for a palindrome (though you may still need to if you want to print the string in reverse), you can just start at both ends and move inward, something like:
char *left = &palstr, right = palstr + strlen(palstr) - 1, ispalin = 1;
while (left < right) {
if (*left++ != *right--) {
ispalin = 0;
break;
}
}
There may be other things I've missed but that should be enough to start on.
well, the are so many bugs in this code. I will point them out with comments.
#include <stdio.h>
#include <string.h>
int main() {
char palstr[100], ans[100];
printf("enter the string for checking weather the string is a palindrome or not\n");
scanf("%s", palstr); // your former code won't stop input util Ctrl+D
int ispalin = 1, i = 0, n = 0;
int num = strlen(palstr);
printf("the total length of the string is %d\n", num);
while (i < num) { // < insted of <=
if (palstr[i] == ' ' || palstr[i] == ',' || palstr[i] == '.' ||
palstr[i] == '!' || palstr[i] == '?') {
i++;
continue;// without this, marks still in the string
}
palstr[n++] = palstr[i++]; //should be =
}
palstr[n] = '\0'; //
num = n; // the length might be changed
i = 0;
int j = num-1; // reverse
while (i < num) { //
ans[i++] = palstr[j--]; //
}
ans[i] = '\0'; //
printf("the reverse of the string %s is %s\n", palstr, ans);
//if (ans == palstr) they can never be equal
if (strcmp(ans, palstr)==0)
printf("the string is a palindrome\n");
else
printf("the string is not a palindrome\n");
return 0;
}
I'm trying to produce a simple program which will read a string and print it along with the number of characters in it.
The character count seems fine, but it won't print the full string. For whatever reason, it will print only the second character. I have been reviewing my code and I still cannot figure out why this is happening.
If I input: abcdef
It will print out: 1
b 2
3
4
5
6
Instead of the intended: a 1 b 2 c 3 d 4 e 5 f 6
#include <stdio.h>
int main()
{
char c;
char str[0] = {};
int i;
int charcount;
charcount = 0;
for (i = 0; (c = getchar()) != '#' && c != '\n'; i++) {
c = str[i];
charcount++;
printf("%c %d \n", str[i], charcount);
//if(charcount > 80)
// printf("%d", z[i]);
}
return 0;
}
Any help is appreciated. Thanks.
You have a variable str that is of zero length, and you try to access various elements in it (but it has none, so this is undefined behavior)
Just get rid of it and use c directly:
#include <stdio.h>
int main()
{
char c;
int i;
int charcount;
charcount = 0;
for (i = 0; (c = getchar()) != '#' && c != '\n'; i++) {
charcount++;
printf("%c %d \n", c, charcount);
}
return 0;
}
For starters according to the C Standard the function main without parameters shall be declared like
int main( void )
This declaration
char str[0] = {};
is invalid with two respects. The array size shall be greater than zero. And the the braces that initialize the array shall not be empty.
In fact the array is redundant because what you are trying to do is just output entered characters.
This assignment
c = str[i];
does not make sense even if the array was be declared correctly because the entered character is overwritten by the (non-existent) element of the array.
The variable c itself should have the type int.
If you just need to perform this
I'm trying to produce a simple program which will read a string and
print it along with the number of characters in it.
then the program can look for example the following way
#include <stdio.h>
int main(void)
{
size_t i = 0;
for ( int c = getchar(); c != EOF && c != '\n' && c != '#'; c = getchar() )
{
++i;
printf( "%c %zu ", c, i );
}
putchar( '\n' );
return 0;
}
If to enter
abcdef
then the output will be
a 1 b 2 c 3 d 4 e 5 f 6
If you want to use a character array and store entered characters in the array then the program can look like
#include <stdio.h>
int main(void)
{
enum { N = 100 };
char s[N];
int c;
for ( size_t i = 0; i < N && ( c = getchar( ) ) != EOF && c != '\n' && c != '#'; i++ )
{
s[i] = c;
printf( "%c %zu ", s[i], i + 1 );
}
putchar( '\n' );
return 0;
}
The program output will be the same as above if to enter for example abcdef.
I took your question to mean you were looking to store the characters that are entered into an array and print them out as you go. You want to give the array an initial size (I chose 99) and then add characters to the array as you go. You can keep track of the length so you know where the "end" is. There are better ways to manage string data in C, but here you go.
#include <stdio.h>
int main()
{
char c;
char str[99] = {};
int i;
int charcount;
charcount = 0;
for (i = 0; (c = getchar()) != '#' && c != '\n'; i++) {
// c = str[i];
str[i] = c;
charcount++;
printf("%c %d \n", str[i], charcount);
//if(charcount > 80)
// printf("%d", z[i]);
}
return 0;
}
Some additional thoughts:
You probably want to look at something like string.h
If you are going to keep the char array, you need to protect against going over the size of the array
Adding a little blurb about what you expect your program to do, what the requirements are, example input, output, etc would have helped get better answers from the community
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
So im supposed to write a Soundex Converter code and print the lines from a file if one of its words has the same Soundex code as the input. I successfully wrote a function for the Soundex conversion but im stuck at the comparing part. Sorry if this sounds trivial but when i compare the words line by line, strcmp seems to fail everytime. Here's the code... Sorry if its too long
#include<string.h>
#include<ctype.h>
#include<stdio.h>
#include<stdlib.h>
char *soundex(char *s,char* name)
{
int si = 1;
char c;
//char *s = (char *)malloc(1000);
// ABCDEFGHIJKLMNOPQRSTUVWXYZ
char mappings[] = "01230120022455012623010202";
s[0] = toupper(name[0]);
for(int i = 1, l = strlen(name); i < l; i++)
{
c = toupper(name[i]) - 65;
if(c >= 0 && c <= 25)
{
if(mappings[c] != '0')
{
if(mappings[c] != s[si-1])
{
s[si] = mappings[c];
si++;
}
if(si > 3)
{
break;
}
}
}
}
if(si <= 3)
{
while(si <= 3)
{
s[si] = '0';
si++;
}
}
//printf("%s\n",s);
return s;
}
void search(char line[10000],char str[1000])
{
int i,j=0;
char test[1000];
char s[1000];
char b[1000];
for(i=0;line[i] != '\0';i++)
{
if(line[i] == ' ')
continue;
test[j] = line[i];
j++;
if(line[i+1] == ' ' || line[i+1] == '\0')
{
//soundex(test);
test[j] = '\0';
if(strcmp(soundex(s,test),soundex(b,str)) == 0);
{
printf("%s\n",soundex(s,test));
printf("%s\n",soundex(b,str));
printf("%s",line);
break;
}
j = 0;
memset(test,0,strlen(test));
}
}
}
int main()
{
char a[1000],f[1000];
char s[1000];
gets(a);
//soundex(s,a);
//printf("%s",s);
scanf("%s",f);
FILE *fp=fopen(f,"r");
if(fp==NULL)
{
printf("File doesnot exist bro");
}
else
{
long long linenum=1;
char line[10000];
while(fgets(line,10000,fp)!=NULL) //Or fscanf
{
search(line,a);
//printf("%s",line);
linenum++;
}
}
fclose(fp);
}
The Problem is arising with the strcmp command in the Search function as it prints the lines even after the results differ. I even print the results of the comparison afterwards to be sure. Any leads would be aprreciated. Again sorry for the long code.
Take the ; off. Don't ignore compiler warnings!
prog.c:70:17: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
if(strcmp(soundex(s,test),soundex(b,str)) == 0);
if(strcmp(soundex(s,test),soundex(b,str)) == 0)
also
prog.c: In function ‘search’:
prog.c:68:25: warning: statement with no effect [-Wunused-value]
test[j] == '\0';
and
prog.c: In function ‘main’:
prog.c:89:9: warning: implicit declaration of function ‘gets’ [-Wimplicit-function-declaration]
gets(a);
I am writing C program that reads input from the standard input a line of characters.Then output the line of characters in reverse order.
it doesn't print reversed array, instead it prints the regular array.
Can anyone help me?
What am I doing wrong?
main()
{
int count;
int MAX_SIZE = 20;
char c;
char arr[MAX_SIZE];
char revArr[MAX_SIZE];
while(c != EOF)
{
count = 0;
c = getchar();
arr[count++] = c;
getReverse(revArr, arr);
printf("%s", revArr);
if (c == '\n')
{
printf("\n");
count = 0;
}
}
}
void getReverse(char dest[], char src[])
{
int i, j, n = sizeof(src);
for (i = n - 1, j = 0; i >= 0; i--)
{
j = 0;
dest[j] = src[i];
j++;
}
}
You have quite a few problems in there. The first is that there is no prototype in scope for getReverse() when you use it in main(). You should either provide a prototype or just move getReverse() to above main() so that main() knows about it.
The second is the fact that you're trying to reverse the string after every character being entered, and that your input method is not quite right (it checks an indeterminate c before ever getting a character). It would be better as something like this:
count = 0;
c = getchar();
while (c != EOF) {
arr[count++] = c;
c = getchar();
}
arr[count] = '\0';
That will get you a proper C string albeit one with a newline on the end, and even possibly a multi-line string, which doesn't match your specs ("reads input from the standard input a line of characters"). If you want a newline or file-end to terminate input, you can use this instead:
count = 0;
c = getchar();
while ((c != '\n') && (c != EOF)) {
arr[count++] = c;
c = getchar();
}
arr[count] = '\0';
And, on top of that, c should actually be an int, not a char, because it has to be able to store every possible character plus the EOF marker.
Your getReverse() function also has problems, mainly due to the fact it's not putting an end-string marker at the end of the array but also because it uses the wrong size (sizeof rather than strlen) and because it appears to re-initialise j every time through the loop. In any case, it can be greatly simplified:
void getReverse (char *dest, char *src) {
int i = strlen(src) - 1, j = 0;
while (i >= 0) {
dest[j] = src[i];
j++;
i--;
}
dest[j] = '\0';
}
or, once you're a proficient coder:
void getReverse (char *dest, char *src) {
int i = strlen(src) - 1, j = 0;
while (i >= 0)
dest[j++] = src[i--];
dest[j] = '\0';
}
If you need a main program which gives you reversed characters for each line, you can do that with something like this:
int main (void) {
int count;
int MAX_SIZE = 20;
int c;
char arr[MAX_SIZE];
char revArr[MAX_SIZE];
c = getchar();
count = 0;
while(c != EOF) {
if (c != '\n') {
arr[count++] = c;
c = getchar();
continue;
}
arr[count] = '\0';
getReverse(revArr, arr);
printf("'%s' => '%s'\n", arr, revArr);
count = 0;
c = getchar();
}
return 0;
}
which, on a sample run, shows:
pax> ./testprog
hello
'hello' => 'olleh'
goodbye
'goodbye' => 'eybdoog'
a man a plan a canal panama
'a man a plan a canal panama' => 'amanap lanac a nalp a nam a'
Your 'count' variable goes to 0 every time the while loop runs.
Count is initialised to 0 everytime the loop is entered
you are sending the array with each character for reversal which is not a very bright thing to do but won't create problems. Rather, first store all the characters in the array and send it once to the getreverse function after the array is complete.
sizeof(src) will not give the number of characters. How about you send i after the loop was terminated in main as a parameter too. Ofcourse there are many ways and various function but since it seems like you are in the initial stages, you can try up strlen and other such functions.
you have initialised j to 0 in the for loop but again, specifying it INSIDE the loop will initialise the value everytime its run from the top hence j ends up not incrmenting. So remore the j=0 and i=0 from INSIDE the loop since you only need to get it initialised once.
check this out
#include <stdio.h>
#include <ctype.h>
void getReverse(char dest[], char src[], int count);
int main()
{
// *always* initialize variables
int count = 0;
const int MaxLen = 20; // max length string, leave upper case names for MACROS
const int MaxSize = MaxLen + 1; // add one for ending \0
int c = '\0';
char arr[MaxSize] = {0};
char revArr[MaxSize] = {0};
// first collect characters to be reversed
// note that input is buffered so user could enter more than MAX_SIZE
do
{
c = fgetc(stdin);
if ( c != EOF && (isalpha(c) || isdigit(c))) // only consider "proper" characters
{
arr[count++] = (char)c;
}
}
while(c != EOF && c != '\n' && count < MaxLen); // EOF or Newline or MaxLen
getReverse( revArr, arr, count );
printf("%s\n", revArr);
return 0;
}
void getReverse(char dest[], char src[], int count)
{
int i = count - 1;
int j = 0;
while ( i > -1 )
{
dest[j++] = src[i--];
}
}
Dealing with strings is a rich source of bugs in C, because even simple operations like copying and modifying require thinking about issues of allocation and storage. This problem though can be simplified considerably by thinking of the input and output not as strings but as streams of characters, and relying on recursion and local storage to handle all allocation.
The following is a complete program that will read one line of standard input and print its reverse to standard output, with the length of the input limited only by the growth of the stack:
int florb (int c) { return c == '\n' ? c : putchar(florb(getchar())), c; }
main() { florb('-'); }
..or check this
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
char *my_rev(const char *source);
int main(void)
{
char *stringA;
stringA = malloc(MAX); /* memory allocation for 100 characters */
if(stringA == NULL) /* if malloc returns NULL error msg is printed and program exits */
{
fprintf(stdout, "Out of memory error\n");
exit(1);
}
else
{
fprintf(stdout, "Type a string:\n");
fgets(stringA, MAX, stdin);
my_rev(stringA);
}
return 0;
}
char *my_rev(const char *source) /* const makes sure that function does not modify the value pointed to by source pointer */
{
int len = 0; /* first function calculates the length of the string */
while(*source != '\n') /* fgets preserves terminating newline, that's why \n is used instead of \0 */
{
len++;
*source++;
}
len--; /* length calculation includes newline, so length is subtracted by one */
*source--; /* pointer moved to point to last character instead of \n */
int b;
for(b = len; b >= 0; b--) /* for loop prints string in reverse order */
{
fprintf(stdout, "%c", *source);
len--;
*source--;
}
return;
}
Output looks like this:
Type a string:
writing about C programming
gnimmargorp C tuoba gnitirw
Using only stdio.h, string.h and stdlib.h libraries how would I go about implementing this?
I'm quite new to programming so please bear with me!
Allocate a new char array of the same length as your string. Convince yourself that this is enough space. Don't forget the NUL.
Loop through the string, copying to the new string only those characters that are alphanumeric. You can't do this portably without also including <ctype.h> and using a function/macro from that header, unless you're going to enumerate all characters that you consider alphanumeric.
Again, don't forget the NUL.
Since this is homework, here is the verbal description:
Run a loop over the original string and use the functions isalnum() to determine if a character is alphanumeric. Maintain a second char array of reasonable size and every time you encounter an AlphaNum, insert it to that array. Once all AlphaNum characters have been copied to the second array, NULL terminate it and you have your string.
Note: isalnum() is defined in ctype.h, so if you aren't allowed to use that, you may have to define this function for yourself. That is another exercise of it's own.
Every char you read in your string is a byte (you can think it as a number between 0 and 255, and that's how the computers handle them) so you just need to check the ascii table to see what letter refers to.
Every alphanumerical char is in this range: [48, 58] (for numbers), or [65, 90] (upper case), or [97, 122] (lower case).
Look at this:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 64
int isalphanum(char); /*states if a char is alphanumerical or not*/
char *getalphanum(char *, char*); /*modifies the second string to get the result*/
int main(void) {
char in[SIZE] = "Hello, W##########orl...,.,d!"; /*just a random to try out*/
char out[SIZE];
getalphanum(in, out);
printf("%s", out);
return 0;
}
int isalphanum(char a) {
if ((a >= 48) && (a <= 58))
return 1;
if ((a >= 65) && (a <= 90))
return 1;
if ((a >= 97) && (a <= 122))
return 1;
return 0;
}
char *getalphanum(char *s, char *t) {
if ((s == NULL) || (t == NULL)) /*tests if the strings are "handble"*/
return NULL;
int i = 0;
int j = 0;
char c;
while ((c = *(s + i)) != '\0') {
if (isalphanum(c)){
*(t + j) = c;
j++;
}
i++;
}
*(t + j) = '\0';
return t;
}
This code works and is very simple and can be improved, but there is evertything you need.
The best way is to use the isalnum() from ctype.h but now that is not an option, I have written a not-standard/non-portable function called isalnum_not_prefered() which is the equivalent of ctype.h's isalnum().
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int isalnum_not_prefered(char s)
{
if((s >= 'A' && s <= 'Z') ||
(s >= 'a' && s <= 'z') ||
(s >= '0' && s <= '9'))
return 1;
return 0;
}
int main(void)
{
char str[] = "this!234$#&##$^is5##$a##$4677~=_?}valid2234kjstring";
int len = strlen(str);
int i, j=0;
char *newstr1 = NULL;
char *newstr2 = NULL;
if ((newstr1 = (char *) malloc(sizeof(char) * len + 1)) == NULL) {
printf("unable to allocate memory \n");
return -1;
}
for (i=0 ; i<len ; i++) {
if (isalnum(str[i])) {
newstr1[j] = str[i];
j++;
}
}
newstr1[j] = '\0';
if ((newstr2 = (char *) malloc(sizeof(char) * len + 1)) == NULL) {
printf("unable to allocate memory \n");
return -1;
}
j=0;
for (i=0 ; i<len ; i++) {
if (isalnum_not_prefered(str[i])) {
newstr2[j] = str[i];
j++;
}
}
newstr2[j] = '\0';
printf("string : %s \n", str);
printf("result1 : %s \n", newstr1);
printf("result2 : %s \n", newstr2);
free(newstr1);
free(newstr2);
return 0;
}
Points to note:
strings in C is terminated with \0. So the new string that your are populating should also terminate with \0
malloc()'ed memory must be free()'ed
malloc() errors should be handled
this code is not portable as it assumes the machines character set to be ASCII. If the hardware supports some other character set (say EBCDIC) then this may not work as expected.
Hope this helps!