Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
What I've done is ask a user to input how many times the program will loop, it then records values into 3 different arrays. Everything is working great, but what I need it to do is print the elements of one array if the corresponding element in another array meets the requirements. Everything else runs great, I'll post the two arrays that I'm trying to use for this.
char *names[50][32];
char *states[50][2];
i = 0;
while ( i < b) {
if (state[i] = "tx");{
printf("a string %s\n", names[i]);}
i = i + 1;
}
for this : if (state[i] = "tx");{ I've tried with and without quotes and using 116120...
Basically, it asks for peoples names and where they live. I can get it to print the array element values for each name(it runs in a loop) but I want it to only print the names for the people who live in tx.
There are a few things wrong with your code. First of all ending an if or for construction with a semicolon is a common mistake when starting in C. Basically it creates an empty if statement followed by a code block. Look at it this way:
if (condition)
; // Does nothing. The if is empty
// Totally unrelated block of code.
{
}
Code blocks are usually useful to create scopes, so although it might seem useless for the compiler to interpret blocks in this way, it actually is not. This also happens in other situations, such as while, for, and so on:
for (int i=0 ; i<n ; ++i)
; // Empty for. Runs `n` loops, but doing nothing
// Unrelated block of code. Runs only once
{
}
The comparison operator is also wrong, you should use == for comparisons, instead of =, which is used for assignments.
Finally, you cannot compare strings in this way. Strings are basically arrays, which in turn are represented using pointers. If you compare two pointers (ptr1 == ptr2) it'll only check whether the two strings point at the same address in memory. As strings are composed by several characters, they have to be iterated to be properly compared. Fortunately the standard library already provides a method for this.
Fix a typo or two and this is what you get:
char *names[50][32];
char *states[50][2];
i = 0; // Assuming this is declared somewhere else
while ( i < b) {
if (strcmp(states[i], "tx") == 0) {
printf("a string %s\n", names[i]);
}
i = i + 1;
}
You should probably also check the docs for strcmp.
Edit: as this is already the accepted answer, I should also include a fix as noted by #dbush. The array for stats is clearly missing space for the extra string terminator, as strings are NULL terminated in C. The array for names might or might not suffer from the same issue, it's not clear. Anyway, it's notable that both should include an extra byte for storing the terminator:
char names[50][33];
char states[50][3];
Props to #dbush.
The declaration of your arrays don't look correct:
char *names[50][32];
char *states[50][2];
These declare a pair of two-dimensional array of char pointers, which is probably not what you want.
char names[50][32];
char states[50][3];
These are two-dimensional arrays of characters, or alternately arrays of strings. Note that the states array has space for an extra character for the terminating NULL.
In this if statement this:
if (state[i] = "tx");{
Since the ; occurs immediately after the condition, that ends the if block. The following statements within curly braces therefore will always run. Also, = is for assignment, not comparison, but using == is not appropriate either, since that operator won't compare the strings, but their addresses. You need to use strcmp for string comparisons.
So the fixed code should look like this:
char names[50][32];
char states[50][3];
...
i = 0;
while ( i < b) {
if (strcmp(state[i],"tx") == 0) {
printf("a string %s\n", names[i]);
}
i = i + 1;
}
Related
I got the task in university to realize an input of a maximum of 10 integers, which shall be stored in a one dimensional vector. Afterwards, every integer of the vector needs to be displayed on the display (via printf).
However, I don't know how to check the vector for each number. I thought something along the lines of letting the pointer of the vector run from 0 to 9 and comparing the value of each element with all elements again, but I am sure there is a much smarter way. I don't in any case know how to code this idea since I am new to C.
Here is what I have tried:
#include <stdio.h>
int main(void)
{
int vector[10];
int a;
int b;
int c;
a = 0;
b = 0;
c = 0;
printf("Please input 10 integers.\n\n");
while (a <= 10);
{
for (scanf_s("%lf", &vektor[a]) == 0)
{
printf("This is not an integer. Please try again.\n");
fflush(stdin);
}
a++;
}
for (b <= 10);
{
if (vector[b] != vector[c]);
{
printf("&d", vector[b]);
c++;
}
b++;
}
return 0;
}
Your code has several problems, some syntactic and some semantic. Your compiler will help with many of the former kind, such as
misspelling of variable name vector in one place (though perhaps this was a missed after-the-fact edit), and
incorrect syntax for a for loop
Some compilers will notice that your scanf format is mismatched with the corresponding argument. Also, you might even get a warning that clues you in to the semicolons that are erroneously placed between your loop headers and their intended bodies. I don't know any compiler that would warn you that bad input will cause your input loop to spin indefinitely, however.
But I guess the most significant issue is that the details of your approach to printing only non-duplicate elements simply will not serve. For this purpose, I recommend figuring out how to describe in words how the computer (or a person) should solve the problem before trying to write C code to implement it. These are really two different exercises, especially for someone whose familiarity with C is limited. You can reason about the prose description without being bogged down and distracted by C syntax.
For example, here are some words that might suit:
Consider each element, E, of the array in turn, from first to last.
Check all the elements preceding E in the array for one that contains the same value.
If none of the elements before E contains the same value as E then E contains the first appearance of its value, so print it. Otherwise, E's value was already printed when some previous element was processed, so do not print it again.
Consider the next E, if any (go back to step 1).
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
There is no Standard function in C to take a string, break it up at whitespace
or other delimiters, and create an array of pointers to char, in one step.
If you want to do that sort of thing, you have to do it yourself, either
completely by hand, or by calling e.g. strspn and strpbrk in a loop,
or by calling strtok in a loop, or by calling strsep in a loop.
I am not asking how to do this. I know how to do this,
and there are plenty of
other questions
on Stackoverflow
about how to do it. What I'm asking is if there are any good reasons why
there's no such function.
I know the two main reasons, of course: "Because no mainstream compiler/library
ever had one" and "Because the C Standard didn't specify one, either (because
it likes to standardize existing practice)." But are there any other reasons?
(Are there arguments that such a function is an actively bad idea?)
This is usually a lame and pointless sort of question, I know. In this case
I'm fixated on it because convenient splitting is such a massively useful
operation. I wrote my own string splitter within my first year as a
C programmer, I think, and it's been a huge productivity enhancer for me ever
since. There are dozens of questions here on SO every day that could be
answered easily (or that wouldn't even have to be asked) if there were a
standard split function that everyone could use and refer to.
To be clear, the function I'm imagining would have a signature like
int split(char *string, char **argv, int maxargs, const char *delim)
It would break up string into at most maxargs substrings, splitting on one or more characters from delim, placing pointers to the substrings into argv, and modifying string in the process.
And to head off an argument I'm sure someone will make: although it's standard, I do not consider
strtok to be an effective solution. strtok, frankly, sucks. Saying "you don't need a split function,
because strtok exists" is a lot like saying "You don't need printf,
because puts exists." This is not a question about what's theoretically
possible with a given toolset; it's about what's useful and convenient. The more
fundamental issue here, I guess, concerns the ineffable tradeoffs involved
in picking tools that are leverageable and productivity-enhancing and that
"pay their way". (I think it's clear that a nicely encapsulated
string-splitting function would pay its way handsomely, but perhaps
that's just me.)
I will try an answer. I indeed agree that such a function would be usefull. It is often quite usefull in the languages that have one.
Basically you are suggesting a builtin very simple wrapper around strtok() or strtok_r(). It would be a less powefull version (as we can't change delimiter while processing) but still usefull in some cases.
What I see is that these cases are also overlapping with scanf() familly functions use cases and with getopt() or getsubopt() familly functions use cases.
Actually I'm not sure that the remaining real use cases are that common.
In real life non trivial cases you would need a true parser or regex library, in specialized common case you already have scanf() or getopt() or even strtok().
Also functions modifying their input strings like strtok() or yours are more or less deprecated these days (experience says they easily lead to troubles).
Most languages providing a split feature have a real string type, often an unmutable one, and are supporting it by creating many individual substrings while leaving the original string intact.
Following that path would lead to either some other API non based on zero delimited strings (maybe with a start pointer and and end pointer), or with allocated string copies (like when using strdup()). Neither really satisfying.
In the end, if you add up not so common use in real life, quite simple to write and not that simple or intuitive API, there is no wonder that such function wasn't included in strandard libc.
Basically I would write something like that:
#include <string.h>
#include <stdio.h>
int split(char *string, char **argv, int maxargs, const char *delim){
char * saveptr = 0;
int x = 0;
argv[x++] = strtok_r(string, delim, &saveptr);
while(argv[x-1] && (x <= maxargs)){
argv[x++] = strtok_r(0, delim, &saveptr);
}
return x-1;
}
int main(){
char * args[10];
{
char * str = strdup("un deux trois quatre cinq six sept huit neuf dix onze");
int res = split(str, args, sizeof(args)/sizeof(char*), " ");
printf("res = %d\n", res);
for(int x = 0; x < res ; x++){
printf("%d:%s\n", x, args[x]);
}
}
{
char * str = strdup("un deux trois quatre cinq");
int res = split(str, args, sizeof(args)/sizeof(char*), " ");
printf("res = %d\n", res);
for(int x = 0; x < res ; x++){
printf("%d:%s\n", x, args[x]);
}
}
}
What I see looking at the code is that the wanted function is really very simple to write using strtok()... and that the call site to use the result is nearly as complicated than the function itself. In such a case hencefore I'd rather inline the function on the call site than having to call libc.
But of course you are welcome to use and write yours if you believe it's simpler for you.
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 6 years ago.
Improve this question
struct sign_in
{
char password[MAX_NAME_LEN+1];//The password for each player
char name[MAX_NAME_LEN+1];//Name of the people who can sign in
}
//prototype
int compare_names(char*, char*, struct sign_in*);
int compare_names(char*pName,char*pPassCode,struct sign_in *var)
{
int iComparison = 1;
int flag = 1;
int iComparison2 = 1;
int i = 0;
for (i=0;i<6;i++)
{
printf("%s \t %s ", var[0].name,pName );
if(iComparison != 0)
{
iComparison = strcmp(pName,var[i].name);
i++;
}
if(iComparison2 != 0)
{
iComparison2 = strcmp(pPassCode,var[i].password);
i++;
}
printf("%d", iComparison);
printf("%d", iComparison2);
}
}
I have updated my code and attempted to take into account many of the aspects that you guys have recommended and the good news is that it runs now. The bad news is that it still attempts to print some random jargon that I don't understand, it's just a collection of symbols usually. The structure this function compares against has six members so that's the reason for parameters on the first for loop.
The code you've presented is a cornucopia of sloppyness. When programming, that's not really OK.
You forgot the closing curly braces for the struct sign_in definition and the compare_names() function definition
You did not initialize iComparisson to any value. flag is initialized, but iComparisson is not. Also, it's misspelled!
Don't use printf() with a user-input as the format string, there could be a % in there. At the very least do printf("%s", pname). And you probably want a \n in there too.
strcmp() might return -1 to mean pName sorts before var[i].name (and differs from it of course), so while(iComparisson == 1) does not do what you want
you need to know the length of the var array and stop that loop before you run off the end
strcmp() takes strings, which are pointers. When you call strcmp(*pName, ...) you're dereferencing the pName "pointer to char" to just a "char". It's like getting the first character from the pName string, and then putting that character value where a pointer-to-character value is expected. Not good. The situation with var[i].name is a bit more complicated because name is an array, but get rid of the star, it's not needed for that either.
The second while () loop will loop forever if the iPassCode does not match, you probably want if ()
In your problem description you omit the closing backtick after *var[i].password and the closing double-quote after "invalid type argument of unaray", and you obviously mangled the compiler error message as well. This makes it harder to understand what you wrote and what went wrong.
The iPassCode == var[i].password actually looks fine. It seems rather likely that this isn't the code you had a problem with, due to all the other ridiculous problems in your sample ...
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have a
char s9[7] = "[abcd]";
How do i remove the brackets [] so that
s9 == "abcd"
I have tried
s9 = s9.Substring(1, s9.Length-2);
throws error in cygwin
a2v2.c:42:13: error: request for member ‘Substring’ in something not a structure or union
a2v2.c:42:29: error: request for member ‘Length’ in something not a structure or union
edit:
i realised my error, i am beginner at c and couldnt differentiate between c and C++ code, regards
Someone will correct me if I'm wrong, since the C standard I know is a couple of decades old, but as far as I know, C doesn't offer any standard support for string manipulation, and in fact doesn't even officially have a concept of strings. (Or of object functions, for that matter.) Instead, C uses pointers, which are much more powerful, but much more dangerous in that you can really mess things up if you don't learn your way around them.
The most important thing, if you want to be a C programmer is that you learn C. At the very least, you need to look up "string manipulation C" and read any of the pages that pop up.
There are many ways to do what you want. I think this is one of the faster ones (though it modifies the string you're looking at. If that matters, choose another way):
// trim off the last character
s9[strlen(s9) - 1] = '\0';
// the char * points to the s9 array. +1 makes it look at
// the second element, so then substring is the string you need
char * substring = s9 + 1;
Skipping any checking that the string actually begins and ends with those characters:
int len = strlen(s9);
for ( i = 0; i < len - 2; ++i )
s9[i] = s9[i + 1];
s9[len - 2] = '\0';
memmove( s9, s9 + 1, 4);
s9[4] = 0;
If it is strictly C, then you will need to use more basic functions (a char[] array has little in common with the string class in C++). Some of the functions to use might be:
strchr: Find the position of a character (e.g., strchr( s9, '[')). This assumes that it is not a fixed format you are dealing with. If you know the length and positions, then you could skip this and simply use memmove directly.
memmove: Shift the character left in the array. In this situation memmove would be needed (over memcpy or strncpy) because the target and destination overlap.
int len = strlen(s9);
memmove(s9, (s9+1), len-2); /* can handle overlapping strings */
s9[len-2] = 0; /* null terminate */
Hello I'm obviously new to C but I'm looking for some help or advice on the logic behind what I want to do.
That being, I'm going to make an array of questions and I'd like to loop through it and print out the questions one at a time.
The catch is that after one question is printed out the program or function waits until it is answered with a "Y" or "N" then the loop continues. Once all questions are answered the results are printed and the program ends.
I just need some advice on the logic behind something like this. Perhaps the use of loops in this instance isn't feasible and I need to try something different, any advice is appreciated!
Well, here is one of a possible multitude of options (you asked for C, so, here's some C code; in C++, this could have been done entirely differently):
You need to define a structure to hold your questions, maybe like this:
#define QUESTION_SZ 128 /* adjust to your needs, or use dynamic memory allocation */
#define ANSWER_SZ 128 /* ditto */
struct question
{
char question_text[QUESTION_SZ];
char answer[ANSWER_SZ];
};
Then, you may create an array of questions and initialize it:
struct question my_poll[32];
Next, you may loop through your array of questions and handle them:
int i = 0;
char *p = NULL;
int oops_we_failed = 0;
for(i = 0; i < 32; i++)
{
printf("Question %d: %s. Your answer?\n", i, my_poll[i].question);
/* fgets() will block until user enters an answer */
p = fgets(my_poll[i].answer, ANSWER_SZ, stdin);
if(NULL == p)
{
/* nothing was read, an error could have happened */
oops_we_failed = 1;
break;
}
else
{
/* now we have a possible answer stored in poll[i].answer */
}
}
Now you have an array of questions and corresponding answers.
You may need to study linked lists to dynamically create polls of arbitrary length.