I want to check if a char array contains all '0's.
I tried this, but it doesn't work:
char array[8];
// ...
if (array == {'0','0','0','0','0','0','0','0'})
// do something
How do I do this?
This
array == {'0','0','0','0','0','0','0','0'}
is definitely wrong, and surely not compiling.
You can compare the values with memcmp() like this
int allZeroes = (memcmp(array, "00000000", 8) == 0);
In fact
array == {'0','0','0','0','0','0','0','0'}
is not allowed, you cannot compare arrays like this. Rather, do it in a loop:
int row_is_all_zeroes(char arr[8])
{
for (int i = 0; i < 8; i++)
{
if (arr[i] != '0')
return 0;
}
return 1;
}
If you want a more elegant solution, have a look at iharob or Sourav's answers
{'0','0','0','0','0','0','0','0'}
is called (and used as) a brace enclosed initializer list. This cannot be used for comparison anywhere.
You can make use of memcmp() to achieve this in an elegant way.
Pseudo-code
if (!memcmp(array, "00000000", 8))
{
break;
}
Related
I'm trying to write a program to break down words into segments/syllables if they are entered in a specific format. I want to enter a word in the format:
[d-i-s][c-o-#][v-er-#]
and store it in the format:
syllable[0]=dis
syllable[1]=co
syllable[2]=ver
So far I have managed to break it into syllables using the delimiter ']' and save it as a char** in the format below:
syllable[0]=[d-i-s
syllable[1]=[c-o-#
syllable[2]=[v-er-#
So now I just want to clean it up and strip out the unnecessary characters! I thought I would make a new array and copy over the letters from the old array so long as they aren't [ - #. But for the life of me I cannot work out how to copy the right letters into another array!!
I know that I cant just do:
cleanArray[i][j] = dirtyArray[i][k]
Because cleanArray[i] is a char* and I can't edit it right? but what can I do?
I've read a lot of similar questions which have suggested strncpy and snprintf (how to copy char array to another char array in C?, strcpy and printf a multidimensional char array C) but I've tried those and I can't make them work. I've even tried putting cleanArray into 3 dimensions in the hope that I would then be able to save the individual letters into cleanArray[i][j] as char*s, which is probably completely wrong.
What is the right way of going about this? Sorry if it's obvious but I've spent hours on it and am now very, very, confused.. I would really appreciate any advice you can give!
Here's my code:
char** cleanStrings (char**dirtyList, int arrayLength)
{
int i, j, k;
char** cleanList = (char**)calloc(arrayLength, CHARLEN);
for (i=0; i<arrayLength; i++)
{
k= 0;
cleanList[i] = (char*)calloc(10,CHARLEN);
for (j=0; j<strlen(dirtyList[i]+1);j++)
{
if (dirtyList[i][j] == '[') continue;
else if (dirtyList[i][j] == '#') continue;
else if (dirtyList[i][j] == '-') continue;
else
//i know this is wrong, but what is the right way of doing it?
cleanList[i][k] = dirtyList[i][j];
k++;
}
}
return cleanList;
}
EDIT
Thanks for all your comments, I've now got it working! Contrary to what I thought, as Barmar points out there is nothing wrong with:
cleanArray[i][j] = dirtyArray[i][k]
My code didn't work because I made a lot of other mistakes like:
-casting the return values of calloc
-not allocating the memory properly for calloc
-incorrect brackets
I also had the code in a header file which I think contained problems of its own.
Assuming that you are using calloc size parameter wrong. One of these char** cleanList = (char**)calloc(arrayLength, CHARLEN); or cleanList[i] = (char*)calloc(10,CHARLEN); is wrong. You also should not cast the return value of a malloc() / calloc(). For legibility and code flow purposes I also replaced ifs statements. You also wrote for (j=0; j<strlen(dirtyList[i]+1);j++) instead of for (j=0; j<strlen(dirtyList[i])+1;j++) because strlen() calculates the length of the string without \0.Here is the code with few changes.
char** cleanStrings (char**dirtyList, int arrayLength)
{
int i, j, k;
char **cleanList = calloc(arrayLength,sizeof * cleanList);
for (i=0; i<arrayLength; i++)
{
k= 0;
cleanList[i] = calloc(10,sizeof * cleanList[i]);
for (j=0; j<strlen(dirtyList[i])+1;j++)
{
if ((dirtyList[i][j] != '[') && (dirtyList[i][j] != '#') && (dirtyList[i][j] != '-') ){
cleanList[i][k] = dirtyList[i][j];
k++;
}
}
}
return cleanList;
}
You're not allocating enough memory for cleanList. I assume CHARLEN is sizeof(char), which is 1 byte. But the elements of cleanList are char*, which is either 4 or 8 bytes, the allocation is much too small. It should be:
char **cleanList = calloc(arrayLength, sizeof(char *));
The general rule when using malloc or calloc is that the multiplier is always sizeof (T), where T is the destination type with one less *. So if you're assigning to char **, it's sizeof(char *).
I have just started leran about C++. And I have to do one exercise but I don't know how. Please help me.
I have to write the function which returns the position of the number in the array,rate and size are pass to this function and the value of the expression|tab[i]_M| is the maximum, where M is the average of all the elements.
Thank you for your help
You will want to look at the values in your array one by one. You can access the individual values like this:
yourarray[index]
The best way to do it is a loop. There are several loops available in C++. You can use the for loop for example. Inside of the loop you check if the value is the one you are looking for
for (int i = 0; ...
{
if your array[i] == your value
If you found the value, break the loop and return the index i.
// Returns the index of the first occurrence of a value in the array, or -1 if not found
int GetPositionInArray(int array[], int value)
{
for (int i = 0; i < sizeof(array)/sizeof(int); i++) {
if (array[i] == value)
return i;
}
return -1;
}
I need all strings starting KAS. For example KAS, KASDGFT, KASddfdd etc.
But in my case it is just KAS. It does not look at KASGHFJHFT, but it starts with KAS. So I need it. I thought to add a regular expression which means nothing or something after KAS like KAS* in strcmp. But it did not work; what should I be doing?
int function (double a, int b, char *program)
{
if (strcmp(program,"KAS")==0){
if (cgpa >= 2 && courses_complete >= 5) {
return 1;
}
} else if (cgpa >= 3 && courses_complete >= 8) {
return 1;
}
return 0;
}
Instead of using strcmp, use strncmp which compares the first n characters.
For example, if (strncmp(program,"KAS",3)==0)
None of the standard C string functions support regular expressions; you'll have to use something outside of the standard C library (such as the GNU extensions) for regular expression matching.
If you only need to search for the substring "KAS", though, you can use strstr:
if ( strstr( program, "KAS" ) )
{
// program contains substring "KAS"
}
Cannot agree any more with Vicky,
and I try to write the function strncmp
int my_strncmp(const char* str1, const char* str2, unsigned int num)
{
unsigned int i = 0;
for( ; (*str1==*str2)&&(*str1!='\0')&&(i<num-1); str1++, str2++, i++)
;
return *str1-*str2;
}
hope can be help
How can I convert the following code to a single line?
int *i;
i = some_func_ret_int_ptr();
if(!i)
{
// Do something
}
// Will use 'i' later
I want to do something like:
if((i=some_func_ret_int_ptr) && !i)
{
// Do something
}
// Will use 'i' later
But I am wasting one comparison here. Is there a better way to do it?
All I want is assignment and comparison in the if and compare only i.
With C, this is as far as you can golf it:
int *i;
if(!(i = some_func_ret_int_ptr()))
{
// do something
}
// Will use i later
In addition to what is suggested in other answers, you can also do it as
if (i = some_func_ret_int_ptr(), !i)
{
// Do something
}
It is a literal implementation of what you had originally, with the statement sequence replaced with an expression sequence separated by the , operator.
It does not make much practical sense, though.
You can do
if(!(i = some_func_ret_int_ptr()))
{
...
}
What happens in this code, in order, is:
The return value of some_func_ret_int_ptr() is assigned to i
The statement !i is checked
If i == 0 what's inside the if gets executed, otherwise it will not
Clean and readable:
int * i = some_func_ret_int_ptr();
if (!i) { /* ... */ }
An option not mentioned yet is:
if ( NULL != (i = some_func()) )
Using the explicit comparison against NULL makes it very easy to read the intent of this code. Especially considering that your function probably won't have ret_int_ptr in its name.
Using the #include <ctype.h> standard library, to get the toupper(char) function, we can write the following function:
void StringToUppercase(char* str)
{
for (int i=0; (str[i] = toupper(str[i])) != 0; i++); // No for-loop body!
// The expression "(str[i] = toupper(str[i]))" executes first and then returns str[i]
}
so that the statement (str[i] = toupper(str[i])) != 0; both assigns a char and checks to see if it is '\0' or not.
The way this works is that part of the C language specifies that assignment expressions have the value of the lefthand expressions after the assignment. For example, with ints, consider the following code snippet:
int x = 5;
int y = x = 8;
// Assignment operators (= += <<=) have right-to-left associativity.
// The expression `(x=8)` returns the value 8, after it has been executed
int z = x != y; // Comparisons have greater (tighter) precedence than assignment
printf("(x, y, z) = (%d, %d, %d)\n", x, y, z); // prints (8, 8, 0)
Same as M.M's answer, but I would go with:
if ((i = some_func_ret_int_ptr()) != NULL)
As it makes the execution order clearer.
I found several answers to this in C++ or C#, but none for C.
I need to know how to count the number of characters in a string. The goal is to determine whether there is a closed block (bounded by braces '{', '}') in a string. right now I have the following:
int closedBlock(char* value) {
int open = 0;
int i;
for (i = 0; i < strlen(value); i++) {
if (!strcmp("{", value[i])) {
open++;
} else if (!strcmp("}", value[i])) {
open--;
}
}
return !open;
}
but it crashes after on the first if check. I'm not really clear on why this does not work. I imagine it has something to do with bad pointers (that seems to always be the problem in C), but I can't figure it out. In addition to working code, and explanation of why mine is bad would be greatly helpful.
Thanks.
NOTE
I am aware that this simply check that the number of '{' is equal to the number of '}', and not truly that there is a properly closed block. I'll solve that problem after I solve this one.
strcmp will compare two null-terminated strings. It still baffles me that your compiler actually doesn't mutter about the second parameter being a char. If you want to compare a single character just use the equal-operator ==:
int closedBlock(char* value) {
int open = 0;
int length = strlen(value);
int i;
for (i = 0; i < length; i++) {
if (value[i] == '{') {
open++;
} else if (value[i] == '}') {
open--;
}
}
return !open;
}
Hint: If you work with gcc add -Wall -Wextra to your compiler call, it will often result in useful warnings.
I am aware that this simply check that the number of '{' is equal to the number of '}', and not truly that there is a properly closed block. I'll solve that problem after I solve this one.
Another hint here: when can there be an invalid block? If and only if the end-token } occurs without a preceding start-token {. You already have all tools for this, you're just missing another if-statement.
It's because you're trying to compare a string: "{" against a single character: value[i].
value (presumably) points to an array of characters, while value[i] specifies a single one of those. So you want to compare character-to-character like so:
for (i = 0; i < strlen(value); i++) {
if (value[i] == '{') {
open++;
} else if (value[i] == '}') {
open--;
}
}
Note the use of single quotes around the { and }. That tells the compiler it's a single character and not a C-string.
why you use strcmp() if you only compare one char?
you can simply use the == operator see my example:
http://ideone.com/dNCH2
best regards kenny