I can't pass strings that contain an apostrophe as a command-line argument.
Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned int ascii_values (const char *word);
int main (int argc, char *argv[])
{
if (argc < 2)
{
printf("Usage: ./ascii WORD\n");
}
for (int i = 1; i < argc; i++)
{
int ascii = ascii_values(argv[i]);
printf("The ascii value is %i\n", ascii);
}
}
unsigned int ascii_values (const char *word)
{
int l = strlen(word);
int ascii = 0;
for(int i = 0; i < l; i++)
{
ascii = word[i];
}
return ascii;
}
If I input the command-line arguments into the terminal:
./ascii '
The following happens and gets stuck there:
>
Instead of:
The ascii value is 39.
Any idea of why it's doing that?
Single quote is a special shell character so you have to escape it. Either enter it as \'or "'".
Related
I have this peace of C Programming code to take multiple literal strings from the user and store each address to each pointer and print out the value
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char *ptr[3];
int i = 0;
for (; i < 3; i++) {
printf("ptr_%d: ", i + 1);
fgets(ptr[i], 15, stdin);
ptr[i][strlen(ptr[i]) - 1] = 0;
puts(ptr[i]);
}
return 0;
}
However, only the first one is printed. Here is the output
ptr_1: first line
first line
Segmentation fault
[Program finished]
I want the same result that is produced Here
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char *ptr[] = {
"first line",
"second line",
"third line"
};
puts(ptr[0]);
puts(ptr[1]);
puts(ptr[2]);
return 0;
}
output
first line
second line
third line
[Program finished]
Thanks in advance
fgets(ptr[i], 15, stdin);
You've declared an array of three pointers:
char *ptr[3];
But none of those actually point to buffers of memory.
You can either create those buffers automatically:
char ptr[3][15];
Or dynamically with malloc.
char *ptr[3];
for (size_t i = 0; i < 3; i++) {
ptr[i] = malloc(15);
}
If you do this, make sure to free the memory you've allocated.
If you are running gcc (with glibc 2.7 or greater), you can use the m modifier with scanf to allocate memory:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char *ptr[3];
for (i = 0; i < 3; i++) {
printf("ptr_%d: ", i + 1);
while (scanf(" %m[^\n]",&ptr[i]) != 1)
printf("Try again: ");
puts(ptr[i]);
}
for (; i < 3; i++)
free(ptr[i]);
return 0;
}
And be sure to free the memory when you are done with it.
You'd probably want to put the scanf section of this code into a function but here is the smallest change to your existing sample that should work.
$ cat allocinput.c
#include <stdio.h>
#include <string.h>
#define MAX_LEN 80
int main(int argc, char *argv[])
{
char c;
char ptr[3][MAX_LEN];
int i = 0;
for (;i<3;i++) {
printf("ptr_%d: ", i + 1);
// could overflow if the user types more than MAX_LEN characters
char *p = ptr[i];
while (scanf("%c", &c) && (p - ptr[i] < MAX_LEN)) {
if (c == '\n') break;
*p++ = c;
*p = 0;
}
puts(ptr[i]);
}
return 0;}
$ gcc -Wall allocinput.c
$ ./a.out
ptr_1: first line
first line
ptr_2: second line
second line
ptr_3: third line
third line
$
P.S. I recommend astyle to clean up the formatting:
$ astyle allocinput.c
Formatted /tmp/overflow/allocinput.c
$ cat allocinput.c
#include <stdio.h>
#include <string.h>
#define MAX_LEN 80
int main(int argc, char *argv[])
{
char c;
char ptr[3][MAX_LEN];
int i = 0;
for (; i<3; i++) {
printf("ptr_%d: ", i + 1);
// could overflow if the user types more than MAX_LEN characters
char *p = ptr[i];
while (scanf("%c", &c) && (p - ptr[i] < MAX_LEN)) {
if (c == '\n') break;
*p++ = c;
*p = 0;
}
puts(ptr[i]);
}
return 0;
}
I'm a newbie, so apologies if I don't explain myself well. If it helps, I'm doing this for the Caesar problem set as part of the Harvard CS50x OpenCourseWare.
I'm trying to convert user generated plain text to cipher text using a simple key. To accomplish this I'm attempting to use a wraparound counting formula in my last function. However, sometimes I get blanks that print out instead of the new characters... Help!
EDIT: I'm using a key of 5 and the plaintext "Helloz!" to test. Expect to see Mjqqte!
instead am seeing blank spaces.
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <stdlib.h>
int convert(string n);
string k, text;
char text;
int r, c, t,x;
bool validate(string n);
//int encrypted(string n);
int main(int argc, string argv[])
{
//accept single command-line argument, non negative integer, k with appropriate error
k = argv[1];
if (argc > 1 && argc <= 2)
{
//printf("Success\n%s\n", argv[1]);
// print individual characters of argv[i]
validate(k);
}
else //if wrong input then print error message and main should return 1
{
printf("Usage: ./caesar key\n");
return 1;
}
text = get_string("plaintext:");
t = atoi(k);
printf("%i\n", t);
convert (text);
printf("\n");
}
//output "ciphertext:" without a newline, with the characters roated by k positions
//after output, print a newline and exit by returning 0 from main
bool validate(string n)
{
for (int i = 0; k[i] != '\0'; i++)
{
if (48 <= k[i] && k[i] <= 57)
{
//printf("%c\n", k[i]);
}
else
{
printf("./caesar key\n");
return 1;
// save for later: printf("%s \n", k);
}
}
return r;
}
int convert(string n)
{
//if fits within a range, Reads individual characters
for (int i = 0; i < text[i]; i++)
{
if (isalpha(text[i]))
{
x = text[i];
//printf("%i\n", x);
c = (x+t) % 26;
// printf("%i\n",c);
printf("%c", c);
}
else
{
printf("%i", text[i]);
}
}
return 0;
}
Here's an implementation that could work for you:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
void convert(char *text, unsigned char k) {
for (unsigned int i = 0; i < strlen(text); i++) {
if (isalpha(text[i])) {
// Contains the 3 leftmost bits, containing the uppercase/lowercase part.
char c = (text[i] / 32) * 32;
// Perform the shifting with modulo on the alphabetic index of the letter.
text[i] = c + ((text[i] % 32) + k) % 26;
}
}
}
int main(int argc, char *argv[]) {
unsigned char k = strtol(argv[1], NULL, 10);
char text[64];
printf("Using key %d.\n", (int) k);
printf("Plaintext: ");
fgets(text, 64, stdin);
// Remove newline.
text[strlen(text) - 1] = 0;
convert(text, k);
printf("Ciphertext: %s.\n", text);
return 0;
}
Test run:
>>> cipher 4
Using key 4.
Plaintext: Test mE Right Away!!1
Ciphertext: Xiwx qI Vmklx Eaec!!1.
I am trying to access each character in a string and add 1 to it before printing out the text. Eg. my code will prompt the user for a text ie. hello and it should print that text plus 1 character(i.e. output "ifmmp" when the input is "hello"). From my code below, instead of a for loop, I am trying to use a while loop to do this however I am running into some issues and it doesn't seem to print the response. Any help greatly appreciated.
// Libraries
#include <cs50.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int main(int argc, string argv[])
{
// If
if (argc == 2 && (atoi(argv[1]) > 0))
for(int i = 0, len = strlen(argv[1]); i < len; i++)
{
char n = argv[1][i];
int digit = isdigit(n);
if (!digit)
{
printf("Usage: ./caesar key\n");
return 1;
}
else
{
string plain = get_string("plaintext: ");
int k = 0;
int len_plain = strlen(plain);
while (len_plain > k)
k++;
char cipher = plain[k];
{
printf("%c\n", cipher);
}
}
}
else
{
printf("Usage: ./caesar key\n");
return 1;
}
}
Your question seems to be:
am trying to access each character in a string and add 1 to it before printing out the text
That can be done in many different ways - here is one example:
#include <stdio.h>
int main(void) {
char str[10] = "hello";
int i = 0;
while(str[i])
{
++str[i]; // Add 1
++i;
}
printf("%s\n", str);
return 0;
}
Output:
ifmmp
I have tried this solution, but don't know why it is giving segmentation fault.
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char st[1000]="";
for (int i=1; i<argc; i++)
{
strcat(st,argv[i][0]);
strcat(st,". ");
}
printf("%s", st);
return 0;
}
A solution without using any string-library functions at all might look like:
#include <stdio.h>
#define ARGV_MAX (5) /* Adjust this to match the maximum number of arguments
to be processed. */
#define RESULT_STR_MAX (3*ARGV_MAX +1) /* The chararacters per arg per maximum arguments
to be processed +1 for the 0-terminator. */
int main(int argc, char *argv[])
{
char st[RESULT_STR_MAX] = "";
size_t string_index = 0;
size_t argv_index = 1; /* Skip argv[0] below as it does not carry an
argument, but the program's name. */
while ((size_t) argc > argv_index
&& RESULT_STR_MAX > string_index /* in fact this or
&& ARGV_MAX >= argv_index) this would do. */
{
st[string_index] = argv[argv_index][0];
string_index++;
st[string_index] = '.';
string_index++;
st[string_index] = ' ';
string_index++;
argv_index++;
}
st[string_index] = '\0'; /* Add the '0'-terminator
to make the char array a "string".
(not necessary as st got initialised to all 0s).*/
if (ARGV_MAX < argv_index)
{
printf("Ignored the last %d argument(s).\n", argc - ARGV_MAX - 1);
}
puts(st);
return 0;
}
Below another approach using strcat():
#include <stdio.h>
#define ARGV_MAX (5) /* Adjust this to match the maximum number of arguments
to be processed. */
#define RESULT_STR_MAX (3*ARGV_MAX +1) /* The chararacters per arg per maximum arguments
to be processed +1 for the 0-terminator. */
int main(int argc, char *argv[])
{
char st[RESULT_STR_MAX] = "";
size_t argv_index = 1; /* Skip argv[0] below as it does not carry an
argument, but the program's name. */
while ((size_t) argc > argv_index
&& ARGV_MAX >= argv_index)
{
strcat(st, (char[2]){argv[argv_index][0]});
strcat(st, ". ");
argv_index++;
}
if (ARGV_MAX < argv_index)
{
printf("Ignored the last %d argument(s).\n", argc - ARGV_MAX - 1);
}
puts(st);
return 0;
}
Change this statement
strcat(st,argv[i][0]);
to
strncat(st, &argv[i][0], 1);
or
strncat(st, argv[i], 1);
In the original statement the function considers the character argv[i][0] as a pointer value. So the call has undefined behavior.
Or you can use a straightforward approach without using string functions. For example
#include <stdio.h>
int main( int argc, char * argv[] )
{
char st[1000];
size_t i = 0;
for ( int j = 1; j < argc; j++ )
{
st[i++] = *argv[j];
if ( j + 1 != argc )
{
st[i++] = ',';
st[i++] = ' ';
}
}
st[i] = '\0';
puts( st );
return 0;
}
try this:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]){
char st[1000]="";
--argc, ++argv;//skip first.
char *p = st;
for (int i = 0; i < argc; i++){
if(i){//between ?
strcpy(p, ". ");
p += 2;
}
*p++ = argv[i][0];//copy one character
}
printf("%s\n", st);
return 0;
}
I'd like to know how I can turn arrays such as {33,44,77,88} or {10,20,30}, that are given given as command line arguments, and turn them from a char to an integer and finally put them into an array of integers.
I've been looking for hours and I cannot find an example where they get the array from the command line and turn it into an integer array.
This is what I had placed at the command line FOO {33,44,77,88} {10,20,30}
My first 4 lines look like this.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
Passing in command-line arguments will pass them in as strings and only strings. Therefore, your argv array will look like this: argv = {"./prog", "FOO", "{33,44,77,88}", "{10,20,30}"};. This means that your passed in array will need to be parsed by your program in order to convert it into an integer array. Try using functions like strtok to parse a string based on a delimiter. Then, once you get the individual numbers, i.e. you have parsed "33", you can use atoi to convert this string into an integer. You will need to build your array up manually.
The following code will interpret any arguments starting with '{' and pull any numbers out that are comma delimited.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
long int* processArray(char* input, int* lng){
int length = 0, i = 0;
while (input[i] != '\0'){
if (input[i] == ',') length ++;
i++;
}
if (length > 0) length ++;
input++;
int j = 0;
long int * out = malloc(length * sizeof(long int));
while(*input != '}'){
while(*input != '\0' && !isdigit(*input)) input++;
if (!isdigit(*input)) break;
out[j++] = strtol(input, &input, 10);
}
*lng = j;
return out;
}
int main(int argc, char ** argv){
int i;
for ( i = 0; i < argc; i++){
// check for variables that look like arrays
if (argv[i][0] == '{'){
printf("Processing '%s'\n", argv[i]);
int l, j;
long int * variables = processArray(argv[i], &l);
printf("Got Array: { ");
for (j = 0; j < l; j++){
printf("%ld%s", variables[j], j == l-1? "" : ", ");
}
printf(" }\n");
}
}
}
Sample output:
./array-args '{ 1, 2, 3 }'
Processing '{1, 2, 3}'
Got Array: { 1, 2, 3 }
i didnt understand your question to 100% but the implementation of what ever you gave will be like this
args.cpp:
#include<iostream>
using namespace std;
int main(int argc, char *argv[])
{
for (int i = 0; i < argc; ++i)
{
std::cout << argv[i] << std::endl;
}
return 0;
}
compilation and output :
~/c++practise>g++ args.cpp
~/c++practise> ./a.out {33,44,77,88} {10,20,30}
./a.out
33
44
77
88
10
20
30