argc = 1 always regardless of how many characters or words in a given sentence - printf

I want to print argc to verify the words are being calculated correctly before moving to next section in my code. My code is:
int main(int argc, char *argv[])
{
string s = get_string("Text: ");
//Read letters;
n = strlen(s);
printf("%d\n", n);
printf("%d\n", argc);
Every time I run the program, argc = 1 always, even though the sentence typed has 4-5 words. I'm not sure why the program is not calculating argc correctly. Any help is greatly appreciated.

So you asked to read text from input and calculate letter & word count:
#include <stdio.h>
#include <ctype.h>
int main()
{
char a[1000] = {0};
//read a line from input
scanf("%[^\n]s", a);
int word_count = 0;
int letter_count = 0;
int idx = 0;
// go through the line
while (a[idx]){
//skip spaces
while(a[idx] && isspace(a[idx]))
idx++;
// if next char is a letter => we found a word
if (a[idx])
word_count++;
//skip the word, increment number of letters
while (a[idx] && !isspace(a[idx])){
letter_count++;
idx++;
}
}
printf("word count = %d letter count = %d", word_count, letter_count);
return 0;
}
EDIT : display line count also
#include <stdio.h>
#include <ctype.h>
int main()
{
char a[1000] = {0};
//read everyting from input until character '0' is found
scanf("%[^0]s", a);
int word_count = 0;
int letter_count = 0;
int sent_count = 0;
int idx = 0;
// go through the lines
while (a[idx]){
//skip spaces
//newline is also a space, check and increment counter if found
while(a[idx] && isspace(a[idx])){
if (a[idx] == '\n')
sent_count++;
idx++;
}
// if next char is a letter => we found a word
if (a[idx])
word_count++;
//skip the word, increment number of letters
while (a[idx] && !isspace(a[idx])){
letter_count++;
idx++;
}
}
printf("word count = %d letter count = %d line count = %d", word_count, letter_count, sent_count);
return 0;
}
Here's another way:
#include <stdio.h>
#include <string.h>
int main()
{
char a[1000] = {0};
int word_count = 0;
int letter_count = 0;
while (1){
scanf("%s", a);
// break when word starts with '0'
if (a[0] == '0')
break;
word_count++;
letter_count += strlen(a);
}
printf("word count = %d letter count = %d", word_count, letter_count);
return 0;
}
This way reads input until word starting with character '0' is found

Related

*** Error in `./text_buffer': corrupted double-linked list: 0x089cbd98 **

I'm trying to make the app using FreeTDS. Following are my code
/*
* Purpose: Test to see if row buffering and blobs works correctly.
* Functions: dbbind dbnextrow dbopen dbresults dbsqlexec dbgetrow
*/
#include "common.h"
#include "stdio.h"
#include<stdlib.h>
#include "readline/readline.h"
#include "readline/history.h"
#include "string.h"
int
main(int argc, char **argv)
{
char failed;
int hasil;
char ch;
char* r = malloc(30);
LOGINREC *login;
DBPROCESS *dbproc;
int i;
int p = 0;
char teststr[1024];
DBINT testint;
read_login_info(argc, argv);
fprintf(stdout, "Starting %s\n", argv[0]);
/* Fortify_EnterScope(); */
while(1)
{
char qrcode[50];
char perintahsql[100] = "select * from REF_COBA where id=";
char *alokasi="";
while(ch != '\n') // terminates if user hit enter
{
ch = getchar();
qrcode[p] = ch;
p++;
}
qrcode[p]='\0';
strcpy(r,qrcode);
alokasi = strsep(&r, ",");
strcpy(r,"");
p=0;
ch = "";
dbinit();
dberrhandle(syb_err_handler);
dbmsghandle(syb_msg_handler);
fprintf(stdout, "About to logon\n");
login = dblogin();
DBSETLPWD(login, PASSWORD);
DBSETLUSER(login, USER);
DBSETLAPP(login, "text_buffer");
//DBSETLHOST(login, "ntbox.dntis.ro");
DBSETLHOST(login, "192.168.1.9");
fprintf(stdout, "About to open\n");
dbproc = dbopen(login, SERVER);
if (strlen(DATABASE))
dbuse(dbproc, DATABASE);
dbloginfree(login);
#ifdef MICROSOFT_DBLIB
dbsetopt(dbproc, DBBUFFER, "100");
#else
dbsetopt(dbproc, DBBUFFER, "100", 0);
#endif
dbcmd(dbproc, strcat(perintahsql,alokasi));
dbsqlexec(dbproc);
if (dbresults(dbproc) != SUCCEED)
{
failed = 1;
fprintf(stdout, "Was expecting a result set.");
exit(1);
}
fprintf(stdout, "select\n");
for (i = 1; i <= dbnumcols(dbproc); i++)
printf("col %d is %s\n", i, dbcolname(dbproc, i));
fprintf(stdout, "setelah for\n");
dbbind(dbproc, 1, INTBIND, 0, (BYTE *) & testint);
dbbind(dbproc, 2, CHARBIND, 0, (BYTE *) teststr);
for (i = 1; i < 2; i++)
{
char expected[1024];
sprintf(expected, "row %03d", i);
if (i % 100 == 0)
{
dbclrbuf(dbproc, 100);
}
if (REG_ROW != dbnextrow(dbproc))
{
failed = 1;
fprintf(stderr, "Failed. Expected a row\n");
//exit(1);
}
else
{
fprintf(stdout, "jalanin usb\n");
printf("Read a row of data -> %d %s\n", (int) testint, teststr);
hasil = system("/opt/usb1rc_linux USB1REL-172 R");
sleep(2);
hasil = system("/opt/usb1rc_linux USB1REL-172 r");
}
}
dbfreebuf(dbproc);
dbexit();
}
return 0;
}
I modified the source from FreeTDS, after compilation there are some warning
bash-4.2# make text_buffer
CC text_buffer.o
text_buffer.c: In function 'main':
text_buffer.c:54:8: warning: assignment makes integer from pointer without a cast [enabled by default]
ch = "";
^
text_buffer.c:18:7: warning: variable 'hasil' set but not used [-Wunused-but-set-variable]
int hasil;
^
text_buffer.c:17:8: warning: variable 'failed' set but not used [-Wunused-but-set-variable]
char failed;
^
CC common.o
CCLD text_buffer
I execute the program without error. This program will check input from user then run the sql command. The format of input shall be , e.g 123456,john doe then press enter. After 50-60 times of input, the double-linked list error will happen.
could anybody help why the error happen?

how to return longest words from an array?

given 2 arrays wrds[] , chars[] as an input to a function such that
wrds[] = [ "abc" , "baa" , "caan" , "an" , "banc" ]
chars[] = [ "a" , "a" , "n" , "c" , "b"]
Function should return the longest word from words[] which can be constructed from the chars in chars[] array.
for above example - "caan" , "banc" should be returned
Note: Once a character in chars[] array is used, it cant be used again.
eg: words[] = [ "aat" ]
characters[] = [ "a" , "t" ]
then word "aat" can't be constructed, since we've only 1 "a" in chars[].
There are kinds of anwers online but they are not written in Objective C.Can anyone help me solve this question in OC?
First, walk through the word array, one word at a time, throwing out all the words that can't be formed from the second array. To do that, for each word, walk through the characters of the word, throwing out that character from the second array. If we come to a character that's not in the second array, that word can't be formed from those characters.
Now we have an array consisting solely of the words that can be formed from those characters. Now sort that array by word length, longest first. Now start walking the array, looking at the length of each word. When that length value changes, stop; you have found all the longest words.
// Program do to do the same in C++
#include <iostream>
#include <string>
#include <map>
#include <vector>
using namespace std;
using std::vector;
vector<char*> match(char** words, int size, char* chars, map<char,int> &second)
{
vector<char*> res;
std::map<char,int> mapi = second;
int currsize = 0;
for(int i = 0; i < size ; i++){
char* wo;
wo = words[i];
int s= 0;
for( s=0; wo[s] != '\0'; s++){
}
if(s < currsize) {
//No need to iterate if already found a bigger word
//continue to see if the next word if bigger of the same size as currsize
continue;
}
// iterate through the map to see if all the letters present in the first array
bool found = true;
for(int j = 0; j <s ; j++){
map<char, int>::iterator it = mapi.find(wo[j]);
if(it == mapi.end()) {
found= false;
break;
}
}
if(!found) {
continue;
}
if(s > currsize) {
//remove the past res as found a bigger one
res.clear();
}
//Store this word in the vector as it is one of the biggest word so far
res.push_back(wo);
currsize = s;
}
return res;
}
int main()
{
map<char, int> leters;
char* words[5] = {"adc", "baa", "caan", "daanns", "banc"};
char ch1[]= {'a', 'a', 'n', 'c', 'b'};
int chsize = sizeof(ch1);
// put the ch1 chars in a map
for(int i = 0; i < chsize; i++) {
map<char,int>::iterator it =leters.find(ch1[i]);
if(it != leters.end()) {
it->second = it->second+1;
} else {
leters.insert(make_pair(ch1[i], 1));
}
}
char* chars = ch1;
vector<char*>v = match(words, 5, ch1, leters);
for(vector<char*>::iterator it = v.begin(); it != v.end(); it++) {
// it will print the result
cout << *it << endl;
}
return 0;
}

Reading file using fscanf in C

I have a fixed format text file to be read in my C program.
The format of the text file is as below:
w 400341a0
r dfcfa8
w 7b034dd4
The first character is always w or r, while the second element is a 32bit hex digit.
I have written the code as below to read this file line by line :
int main (int argc, char *argv[])
{
FILE* file_ptr;
char rw;
uint32_t address;
int file_read;
uint32_t file_line_ctr = 1;
#if(MODE == DEBUG)
{
printf("DEBUG_MODE\n ");
}
#else
{
/*Do Nothing*/
}
#endif
file_ptr = fopen(argv[10], "r");
if (file_ptr == NULL)
{
printf("Can't Open File\n");
}
else
{
printf("File Opened Successfully\n");
}
file_read = fscanf(file_ptr, "%c %x" , &rw, &address);
printf("%c %x \n", rw, address);
while (file_read!= EOF)
{
file_read = fscanf(file_ptr, "%c %x" , &rw, &address);
file_line_ctr ++;
printf("%c %x \n", rw, address);
}
fclose(file_ptr);
printf("File Length = %d \n", file_line_ctr);
return 1;
}
I get the output in the below format for a file with 100000 entries:
w 400341a0
400341a0
r dfcfa8
dfcfa8
w 7b034dd4
7b034dd4
File Length = 200000
Evidently, I am reading the entries twice for some reason, as well as printing them twice.
Can someone figure out why is it so ?
Well. Here is a fix
#include <stdlib.h>
#include <stdio.h>
int main (int argc, char *argv[])
{
FILE* file_ptr;
char rw;
unsigned int address;
int file_read=0;
unsigned int file_line_ctr = 1;
#if(MODE == DEBUG)
{
printf("DEBUG_MODE\n ");
}
#else
{
/*Do Nothing*/
}
#endif
file_ptr = fopen(argv[1], "r");
if (file_ptr == NULL)
{
printf("Can't Open File\n");
}
else
{
printf("File Opened Successfully\n");
}
/*
file_read = fscanf(file_ptr, "%c %x " , &rw, &address);
printf("%c %x \n", rw, address);
*/
while (true)
{
file_read = fscanf(file_ptr, "%c %x " , &rw, &address);
if (file_read == EOF)
break;
file_line_ctr ++;
printf("%c %x \n", rw, address);
}
fclose(file_ptr);
printf("File Length = %d \n", file_line_ctr);
return 1;
}
You will notice that I have added a space after the %x to eat the newlines as white space.
I have also modified your while loop a little to stop the last line being repeat printed. Crude. But it will work until you can rethink the logic. The while (true) may not work with all compilers. I used while (1). Which is non standard but worked for me.

Convert decimal to binary and return array

probably there is a smart way to do that , but anyway i get error on this :
-(int*)decimalBinary:(int)decimal
{
int i=0;
int *bin;
while (decimal!=0)
{
bin[i]=decimal%2;
decimal=decimal/2;
i++;
}
return bin;
}
on the modulo line . why ?
And whats the better way to get it to array ?
Declaring
int *bin;
sets aside space for a pointer but doesn't make it point to an object. It is crucial to initialize bin before using it.
To solve your problem you can declare an array bin[4] in caller function (int main) and then pass *bin to your calling function.
The following code is adapted from This answer on how to print an integer in binary format. Storing "binary digits" into an int array is added into the code below:
#include <stdio.h> /* printf */
#include <stdlib.h> /* strtol */
const char *byte_to_binary(long x);
int main(void)
{
long lVal;
int i, len, array[18];
char buf[18];
{ /* binary string to int */
char *tmp;
char *b = "11010111001010110";
lVal=strtol(b, &tmp, 2); //convert string in "base 2" format to long int
printf("%d\n", lVal);
}
{
printf("%s", byte_to_binary(lVal));
/* byte to binary string */
sprintf(buf,"%s", byte_to_binary(lVal));
}
len = strlen(buf);
for(i=0;i<len;i++)
{ //store binary digits into an array.
array[i] = (buf[i]-'0');
}
getchar();
return 0;
}
const char *byte_to_binary(long x)
{
static char b[17]; //16 bits plus '\0'
b[0] = '\0';
char *p = b;
int z;
for (z = 65536; z > 0; z >>= 1) //2^16
{
*p++ = (x & z) ? '1' : '0';
}
return b;
}

How to use MPI_Reduce to Sum different values from Different groups of processors independently

I am trying to divide my processors into groups then add the summation of each group
independently ... but I couldn't find the result correctly until now.
a simple example is as follows:
int main(int argc, char** argv)
{
int size, rank,i=0,localsum1=0,globalsum1=0,localsum2=0,globalsum2=0;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
if(rank==0)
{
}
else if(rank==1)
{
localsum1 += 5;
MPI_Reduce(&localsum1,&globalsum1,2,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD);
}
else if(rank==2)
{
localsum2 += 10;
MPI_Reduce(&localsum2,&globalsum2,2,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD);
}
if(rank==0)
{
printf("globalsum1 = %d \n",globalsum1);
printf("globalsum2 = %d \n",globalsum2);
}
MPI_Finalize();
return (EXIT_SUCCESS);
}
I can't figure out what is missing here ... can anyone help?
MPI_Reduce is a collective operation. What that means is that all tasks in the participating communicator must make the MPI_Reduce() call. In the above, rank 0 never calls MPI_Reduce() so this program will hang as some of the other processors wait for participation from rank 0 which will never come.
Also, because it is a collective operation on the entire communicator, you need to do some work to partition the reduction. One way is just to reduce an array of ints, and have each processor contribute only to its element in the array:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main(int argc, char** argv)
{
int size, rank;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
int localsum[2] = {0,0};
int globalsum[2] = {0,0};
if(rank % 2 == 1)
{
localsum[0] += 5;
}
else if( rank > 0 && (rank % 2 == 0))
{
localsum[1] += 10;
}
MPI_Reduce(localsum,globalsum,2,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD);
if(rank==0)
{
printf("globalsum1 = %d \n",globalsum[0]);
printf("globalsum2 = %d \n",globalsum[1]);
}
MPI_Finalize();
return (EXIT_SUCCESS);
}
where running now gives
$ mpicc -o reduce reduce.c
$ mpirun -np 3 ./reduce
globalsum1 = 5
globalsum2 = 10
Otherwise, you can create communicators that only connect the processors you want to be involved in each sum, and do the reductions within each commuicator. Below is a not-very-pretty way to do this. This is quite powerful in general but more complicated than the first solution:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main(int argc, char** argv)
{
int size, rank;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
int localsum = 0;
int globalsum = 0;
MPI_Comm comm_evens_plus_root, comm_odds_plus_root;
MPI_Group grp_evens_plus_root, grp_odds_plus_root, grp_world;
MPI_Comm_group(MPI_COMM_WORLD, &grp_world);
int *ranks = malloc((size/2 + 1) * sizeof(rank));
int i,j;
for (i=1, j=0; i<size; i+=2, j+=1)
ranks[j] = i;
MPI_Group_excl(grp_world, j, ranks, &grp_evens_plus_root);
MPI_Comm_create(MPI_COMM_WORLD, grp_evens_plus_root, &comm_evens_plus_root);
for (i=2, j=0; i<size; i+=2, j+=1)
ranks[j] = i;
MPI_Group_excl(grp_world, j, ranks, &grp_odds_plus_root);
MPI_Comm_create(MPI_COMM_WORLD, grp_odds_plus_root, &comm_odds_plus_root);
free(ranks);
if(rank % 2 == 1)
{
localsum += 5;
MPI_Reduce(&localsum,&globalsum,1,MPI_INT,MPI_SUM,0,comm_odds_plus_root);
}
else if( rank > 0 && (rank % 2 == 0))
{
localsum += 10;
MPI_Reduce(&localsum,&globalsum,1,MPI_INT,MPI_SUM,0,comm_evens_plus_root);
}
if(rank==0)
{
MPI_Reduce(&localsum,&globalsum,1,MPI_INT,MPI_SUM,0,comm_odds_plus_root);
printf("globalsum1 = %d \n",globalsum);
MPI_Reduce(&localsum,&globalsum,1,MPI_INT,MPI_SUM,0,comm_evens_plus_root);
printf("globalsum2 = %d \n",globalsum);
}
MPI_Comm_free(&comm_odds_plus_root);
MPI_Comm_free(&comm_evens_plus_root);
MPI_Group_free(&grp_odds_plus_root);
MPI_Group_free(&grp_evens_plus_root);
MPI_Finalize();
return (EXIT_SUCCESS);
}
Running gives
$ mpicc -o reduce2 reduce2.c
$ mpirun -np 3 ./reduce
globalsum1 = 5
globalsum2 = 10