The pset says:
If your program is executed without any command-line arguments, with more than one command-line argument, or with one command-line argument that contains any non-alphabetical character, your program should complain and exit immediately, with main returning 1 (thereby signifying an error that our own tests can detect). [my emphasis]
and welcome to the SE community. As for your question, here goes the answer:
This is really simple, to do so, use the modulus operator, i.e. the % operator.
Te modulus operator returns the remainder when you divide one number by the another, for example, if you perform 200 % 82, it would return 36, in the same way, 100 % 100 would give 0 and so on. Now ...
int c = strlen(argv); strlen(a_string) takes a string as an argument. You have used argv as an argument, an array of strings. If you wanted to get the length of a particular string in the array, for instance, the first parameter of the program invocation, you would use int c = strlen(argv);
Anticipating another issue, here's another example. If you ...
Usually the remainder operator (i.e., %) is used for wrapping around something. The reason is simply because, mathematically, the remainder of dividing an integer a over an integer b is from 0 to b - 1.
Meanwhile, if we have an array of size 5 (indexes: 0, 1, 2, 3, 4). Given x, an integer >= 0, we can securely get a valid index in our 5-element array in ...
world, say hello!
bazba zba zbazb
xoqmd, rby gflkp!
You are doing this:
world, say hello!
xoqmd, szz gflkp!
You are correctly skipping any non-alpha in the plaintext but you are still incrementing the key, because you have tied it to i which keeps incrementing even if the plaintext is non-alpha.
This is a very common error. You've forgotten to include a control character in your output, and it's not showing up in the message from check50 in Terminal because it's a non-printing character.
It's easier to see the problem when you expand one of the failed check tasks in your sandbox link. For instance, the third check (first one to fail) has this line ...
While I haven't tested it, most of your code looks on target at first glance. However, you have a serious problem:
for (k = 0, n = (keyword[k] % strlen(keyword)); k < n; k++)
Your goal is to wrap back to the beginning of the keyword array (your key string) after you use the last element. Let's say that you have a 3 letter key. You want k to go from 0 ...
Well, I'll try to push you in the right direction without giving away the store here.
You say that you understand that you need to use a different index for the key and the plaintext, yet you are using i as the same index for both. They absolutely cannot use the same index. The instant you process a non-alpha, the key will go out of synch.
Next, the index ...
First, notice that the check50 result and your result have different nonsense characters at the end.
Recall from the Week 2 Lecture "More on Strings" (starting around 1:18) the discussion about string termination and the nul character '\0'.
The system expects a string to be terminated with '\0'. This line printf("ciphertext: %s\n", cipher); will print ...
The problem comes because cipher is declared a char array here char cipher[strlen(plain)];, but printed out using a string (aka char*) format here printf("ciphertext: %s\n", cipher);.
Remember, the thing that makes a string a string is the terminating null byte \0. And a string occupies one more byte than strlen to accomodate the terminator.
cipher is not ...
As far as I can see, the problem lies in if(!isalpha(argv[i])). argv is a string of strings. It seems that you wish to access individual elements of second element in argv. If that's the case, then you should probably replace that with if(!isalpha(argv[i])).
Two more points to be mentioned :
isalpha() takes a single character as a parameter and not a ...
Youre mingling things up a little bit, so I suggest you take some fresh air and let your code be more open, for example, change the way you try to print and cipher everything at the same time, use a for loop to cipher each and every letter seperately one by one, that'll allow you to see where exactly your'e going wrong, as itll make things more open.
The types char, short, int, long int, and long long int are often referred to as integer types.
Per its manual, the function atoi takes a value of type const char *. I assume your variable named k is of type char  or char * in which case k[step] would actually be of type char.
There is no implicit conversion of an integer type to a pointer type and that ...
This is a common mistake. Your code requires that the plain text to be encoded and the key are both the same case. You haven't allowed for the scenario where one is uppercase and the other is lowercase or vice versa.
If this answers your question, please accept this answer to remove the question from the unanswered question pool. Let's keep up on forum ...
First of all it might be better for you if you assigned argv to a string variable called keyphrase for example:
char* keyphrase = argv;
Now say keyphrase is "bacon". It would be like that:
keyphrase == 'b'
keyphrase == 'a'
keyphrase == 'c'
keyphrase == 'o'
keyphrase == 'n'
keyphrase == '\0'
and if you do
int length = strlen(...
Look at your tests on the key. Here's one of them:
When you encode a letter, you apply the modulo operation correctly to the key to get the right character, but when you are doing this test, you are checking for isupper() beyond the end of the key.
Instead of doing so many modulo operations in the code to get the right index from ...
Without digging deep into your code, I see two significant problems. They also happen to be the two most common errors on this pset. First, the code uses the same index, i, for both the plain text and the key. (It looks like you started to, with j, but didn't finish implementing it.) The problem with this is that while the plaintext will process every ...
Firstly there are two compilation errors, that will prevent your code from even compiling (making me wonder whether you submitted a different version of your program to the check50).
The first one is the parentheses missing from this line in your
second for loop
I added them in your posted code to make it easier to find.
Inside your ...
Both clauses of the if/else contain return statements. When a return statement is encountered, it will immediately return control to the calling program with no further processing in the current function. Since this is in main, it is terminating the program and returning control to the operating system. The code will never go any farther than the if/else.
You are printing garbage values in the final printf statement:
printf("ciphertext: %s\n", cipher); //printing of ciphered text
You are asking it to print cipher as a string. You declared cipher as a character array like this:
That's fine, but it's not yet a string. printf and other functions like strlen need a character ...
This is a very, very common error for new programmers. The problem is the actual call to isalpha(). The isalpha() function takes a single char as input, but argv is a string, not a char. Simply put, the code is trying to stuff a string down isalpha's throat and it chokes, resulting in a seg fault.
You need to check each char in the string. Hint: a for ...
First issue is that you blindly get argv before actually checking the number of arguments. The segfault, however, comes from the fact you are passing a string to isalpha, whose argument is actually a char (see cs50 reference).
This is a common error on this pset. The code needs two independent index variables to track the position within the plaintext and the key. You have two vars, i and cLength, but they are not independent. cLength is 100% dependent on i.
Here's why. The plaintext index var, i, is incremented for every letter processed for the plaintext. However, cLength, ...
1- The key mustn't be applied until the character is alphabetical, so (- means no encoding)
You are doing this:
String: w o r l d , s a y h e l l o !
Key: b a z b a z b a z b a z b a z b a
While the right approach is:
String: w o r l d , s a y h e l l o !
Key: b a z b a - - z b a - z b a z b -
2- You have forgotten to include a ...
You can nest loops by writing one within the other.
For example, the next piece of code prints the phrase "hello, world!" n x m times
// often known as an outer loop
for (int i = 0; i < n; i++)
// often known as a nested loop
for (int j = 0; j < m; j++)
What you need to do in vigenere is that ...
There are a few subtle problems here. I'm not going to give you the answer directly, but I can give you some hints.
Look at the line of output from check50 relating to the error:
encrypts "world, say hello!" as "xoqmd, rby gflkp!" using "baz" as keyword \ expected output, but not "xosme, tbz ifmmp!\n"
The string argv refers to string of strings. So when you are trying to do argv then it means that you are looking for a string, but you cannot use isalpha(string), because the argument passed to isalpha() is char. It should be like isalpha(argv), where argv refers to the first character in the second string in the list of strings.