Gå til innhold

Funksjon som lager initialer av et navn ?


Anbefalte innlegg

Hei.

Trenger hjelp til å lage en funksjon som skal lage initialer av et navn.

Har foreløpig et program som lager initialer av et navn som består av ett fornavn og ett etternavn:

#include <iostream>
#include <string>
using namespace std;

string lagInitial(string navnet);

int main() {
string navnet;
cout << "Skriv inn fornavn og etternavn: " << endl;
getline(cin, navnet);

int totalLengde = navnet.length(); 
int posMellomrom = navnet.find(' ',0);

int lengdeFornavn   = posMellomrom;
int lengdeEtternavn = totalLengde - posMellomrom - 1;


string fornavn(lengdeFornavn, ' ');
string etternavn(lengdeEtternavn, ' ');

for(int i = 0; i < lengdeFornavn; i++) {
 fornavn[i] = navnet[i];
}
for(int i = posMellomrom + 1; i < totalLengde; i++) {
 etternavn[i - posMellomrom - 1] = navnet[i];
}
cout << "Initialene blir: " <<  lagInitial(fornavn) << lagInitial(etternavn) << endl;
return 0;
}

//Funksjon som lager en initial av ett navn
string lagInitial(string navnet) {
     string returString(2, ' ');
     char bokstaven = navnet[0];
     char storBokstav = toupper(bokstaven);
     returString[0] = storBokstav;
     returString[1] = '.';

     return returString;
}

/*EKSEMPEL PÅ KJØRING AV PROG.:

Skriv inn fornavn og etternavn:
gunnar hansen
Initialene blir: G.H.
*/

 

 

Den nye funksjonen skal altså fungere om man skriver inn

-ett navn, eks "ole" skal bli "O.",

-to navn, eks "ole hansen" skal bli "O.H."

- flere navn, eks "ole kristian bakken hansen" skal bli "O.K.B.H" osv..

 

Takknemlig for all hjelp. :)

Lenke til kommentar
Videoannonse
Annonse

Sikker på at c++ ikke har en explode (ala php) funksjon, split eller noe? Skreiv programmet ditt i python med det samme:

#!/usr/bin/python
# -*-encoding: iso-8859-1-*-
#this script is made by dabear, please retain this notice
def makeInitial(name):
   splits = name.split(' ')
   initials = ''.join([str(x[0].upper()) + '.' for x in splits  if len(x) >=1 ])
   return initials

name = str(raw_input('Skriv inn fornavn og etternavn: '))
print 'Initialene blir: %s'  % makeInitial(name)

Endret av dabear
Lenke til kommentar


#include <string.h>
#ifndef __cplusplus
#include <malloc.h>
#endif

char *initials(char *src)
{
#ifdef __cplusplus
char *ret = new char[32];
#else
char *ret = (char*)malloc(32);
#endif

int i, size = strlen(src);
ret[0] = src[0];
ret[1] = '.';
ret[2] = '\0';
for(i=0;i<size;i++)
{
 if(src[i] == 32)
 {
   i[0] = src[i+1];
   i[1] = '.';
   i[2] = '\0';
   strcat(ret, i);
 }
}
return _strupr(ret);
}

 

husk å bruke delete [] eller free() når du er ferdig med stringen.

 

dette er uten bruk av stl, like greit synes jeg, stl suger.

Lenke til kommentar

std::string inititaler(std::string& navn) {
 size_t pos1,pos2=0;
 std::stringstream ret;
 ret << navn.substr(0,1);
 while((pos1 = navn.find(' ',pos2)) != std::string::npos) {
   ret << "." << navn.substr(pos1+1,1);
   pos2 = pos1+1;
 }
 return ret.str();
}

 

Utestet kode, men burde gjøre susen dersom den funker.

Lenke til kommentar

Takker for svarene. :)

Før jeg fortsetter, må jeg få understreke at jeg er rimelig fersk innen c++, og må ærlig innrømme at svarene nok ble litt for høytflyvende for meg.. :blush:

 

@dabear:

Takker for svaret. Kikket litt etter en slik split-funksjon som du snakket om, men kunne ikke finne noe.

 

 

@GeirGrusom:

Prøvde meg litt frem med den koden som du skrev, men det gikk heller dårlig. Her har jeg prøvd å bruke funksjonen din i et lite testprogram. Det gikk heller dårlig... Kan du se noe umiddelbart som jeg kan prøve å gjøre annerledes ?

#include <iostream>
#include <string>
#include <string.h>
#ifndef __cplusplus
#include <malloc.h>
#endif

using namespace std;

char *initials(char *src);


int main() {
cout << "Skriv inn navnet ditt: " << endl;
string src;
cin >> src;

cout << "Initialene blir: " << initials();
}//main



char *initials(char *src)
{
#ifdef __cplusplus
char *ret = new char[32];
#else
char *ret = (char*)malloc(32);
#endif

int i, size = strlen(src);
ret[0] = src[0];
ret[1] = '.';
ret[2] = '\0';
for(i=0;i<size;i++)
{
if(src[i] == 32)
{
  i[0] = src[i+1];
  i[1] = '.';
  i[2] = '\0';
  strcat(ret, i);
}
}
return _strupr(ret);
}

 

 

@Nazgul:

Samme proiblemet her. Funksjonen du skrev til meg fungerer sikkert helt utmerket, men det blir noe tull når jeg forsøker å implementere den i programmet, og feilmeldingene strømmer på...:

#include <iostream>
#include <string>

using namespace std;

std::string inititaler(std::string& navn);


int main() {

cout << "Skriv inn navnet ditt: " << endl;
string navn;
cin >> navn;

cout << "Initialene blir: " << inititaler() << endl;
}//main



std::string inititaler(std::string& navn) {
size_t pos1,pos2=0;
std::stringstream ret;
ret << navn.substr(0,1);
while((pos1 = navn.find(' ',pos2)) != std::string::npos) {
  ret << "." << navn.substr(pos1+1,1);
  pos2 = pos1+1;
}
return ret.str();
}

 

@alle:

Som nok de fleste skjønner, trenger jeg litt mer hjelp her... :hmm:

Flott om noen kan gi meg ytterligere råd om hvordan dette skal gjøres.. :blush:

Lenke til kommentar

I både GeirGrusom og mitt program må du sende med navnet som et parameter.

I GG sitt tilfelle, initials(src.c_str())

 

I mitt tilfelle initialer(navn).

I tillegg må du inkludere <sstream> (fordi jeg bruker stringstream i funksjonen min)

 

#include <sstream>
#include <iostream>
#include <string>

using namespace std;

std::string inititaler(std::string& navn);


int main() {

cout << "Skriv inn navnet ditt: " << endl;
string navn;
cin >> navn;

cout << "Initialene blir: " << inititaler(navn) << endl;
}//main



std::string inititaler(string& navn) {
size_t pos1,pos2=0;
stringstream ret;
ret << navn.substr(0,1);
while((pos1 = navn.find(' ',pos2)) != string::npos) {
 ret << "." << navn.substr(pos1+1,1);
 pos2 = pos1+1;
}
return ret.str();
}

 

I fremtiden vil du gjerne inkludere de første feilmeldingene fra programmet, så vi lettere kan forstå og hjelpe deg med å rette dem opp.

Lenke til kommentar

Takker for svaret Nazgul. :)

Koden din kompilerer og kjører nå uten noen feilmeldinger, men alt er ikke som det skal.. :hmm: --> Bare den første initialen blir skrevet ut. Eksempel på kjøring:

Skriv inn navnet ditt:
hans petter olsen
Initialene blir: h
Press any key to continue

Som du ser blir "h" skrevet ut, mens det som egentlig skulle blitt skrevet ut er "H.P.O."

Sikkert bare noe småplukk, men stort nok til at jeg står fast.

 

 

 

 

 

Når det gjelder GeirGrusom sin kode har jeg endret den slik du foreslo:

#include <iostream>
#include <string.h>
#ifndef __cplusplus
#include <malloc.h>
#endif

using namespace std;


int main() {
cout << "Skriv inn navnet ditt: " << endl;
string src;
cin >> src;

cout << "Initialene blir: " << initials(src.c_str()) << endl;
}//main


char *initials(char *src)
{
#ifdef __cplusplus
char *ret = new char[32];
#else
char *ret = (char*)malloc(32);
#endif

int i, size = strlen(src);
ret[0] = src[0];
ret[1] = '.';
ret[2] = '\0';
for(i=0;i<size;i++)
{
if(src[i] == 32)
{
  i[0] = src[i+1];
  i[1] = '.';
  i[2] = '\0';
  strcat(ret, i);
}
}
return _strupr(ret);
}

 

Her får jeg nå følgende feilmeldinger:

initial.cpp(35): error C2109: subscript requires array or pointer type

initial.cpp(36): error C2109: subscript requires array or pointer type

initial.cpp(37): error C2109: subscript requires array or pointer type

initial.cpp(20): error C2365: 'initials' : redefinition; previous definition was a 'formerly unknown identifier'

initial.cpp(15): error C2593: 'operator <<' is ambiguous

initial.cpp(38): error C2664: 'strcat' : cannot convert parameter 2 from 'int' to 'const char *'

initial.cpp(13): error C2679: binary '>>' : no operator found which takes a right-hand operand of type 'std::string' (or there is no acceptable conversion)

initial.cpp(15): error C3861: 'initials': identifier not found, even with argument-dependent lookup

initial.cpp(27): warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data

 

Hmm.. :hmm:

Er evig takknemlig for all hjelp. :)

Lenke til kommentar
Jeg skrev noe som skriver ut initialene :p

 

Men koden er forferdelig, i forhold til det dere andre har skrevet.

Tør ikke å vise den.

Jeg skrev noe enkelt for å få det til å funke.

5165084[/snapback]

Så lenge det funker, så har det ingen ting å si hvordan koden "ser ut".

Hadde vært til stor hjelp om du posta den. :)

Lenke til kommentar

the_c, bytt ut cin >> navn; med getline(cin, navn) så funker min fint.

Sorry at jeg ikke så det tidligere.

Grunnen til dette er at cin bare leser frem til første whitespace, så variablen navn inneholder bare ett navn :)

#include <sstream>
#include <iostream>
#include <string>

using namespace std;

string inititaler(std::string& navn);


int main() {

cout << "Skriv inn navnet ditt: " << endl;
string navn;
getline(cin,navn);

cout << "Initialene blir: " << inititaler(navn) << endl;
}//main



string inititaler(string& navn) {
size_t pos1,pos2=0;
stringstream ret;
ret << navn.substr(0,1);
while((pos1 = navn.find(" ",pos2)) != string::npos) {
ret << "." << navn.substr(pos1+1,1);
pos2 = pos1+1;
}
return ret.str();
}

Lenke til kommentar

Du kan jo f.eks. gjøre slik:

#include <iostream>
#include <cstdlib>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
       cout << "Skriv inn navn: ";
       string name;
       getline(cin, name); 

       cout << "Initialene blir: ";

       cout << name[0];
       for(int i = 0; i != name.size(); i++) 
               if(isspace(name[i])) 
                       cout << name[i+1];

       cout << endl;

       return 0;
}

Lenke til kommentar

Og her er en boost-variant:

 

#include <string>
#include <vector>
#include <iostream>
#include <boost/algorithm/string.hpp>


namespace stdx = boost::algorithm;


std::string get_initials(const std::string & name)
{
  std::string result;
  std::vector<std::string> tokens;
 
  stdx::split(tokens, name, stdx::is_any_of(" .-"), 
              stdx::token_compress_on);
 
  for(std::vector<std::string>::iterator it=tokens.begin(); 
      it!=tokens.end(); ++it)
  {
     result += toupper(it->at(0));
  }

  return result;
}


int main()
{
  using std::cout;
  using std::endl;
 
  cout << get_initials("ola nordmann") << endl;
  cout << get_initials("kari l. nordmann") << endl;
  cout << get_initials("hans-ole nordmann") << endl;
  cout << get_initials("o.j. simpson") << endl;
  cout << get_initials("o. j. simpson") << endl;
  cout << get_initials("o. j.     simpson") << endl;
}

 

.. som også takler punktum og bindestrek :)

Endret av kjetil7
Lenke til kommentar

Mitt program blir veldig rotete når man blander C og C++, jeg fikk det til å fungere, ihvertfall min del, men det er en C løsning, og er plundrete å tøyse sammen med C++

 

class string : public object

 

har jeg skrevet selv, 'object' er gjør at klassen blir garbage collected :)

istedet for den plundrete, teite std::string som er en uhåndterlig template, usj jeg hater stl p.g.a. den massive bruken av templates, det er kjekt med templates, men det får da være grenser.

Lenke til kommentar

Hver sin smak. Men å si at stl er teit fordi det bruker templates og du ikke klarer/vil håndtere det er litt drøyt. Personlig er jeg av helt motsatt oppfatning. Jeg mener at STL gjør en super jobb ved å tilfredstille de fleste krav til containere, uten at brukeren må gjøre noe som helst med minnet.

Lenke til kommentar

Har prøvd ut kodene deres, og her er hva jeg har kommet frem til så langt.

 

@prog master

Programmet ditt fungerer, men poenget var at hele navnet skulle leses inn på en gang, ikke ett og ett navn. Setter pris på innspillet tho.

 

@Nazgul

Funksjonen din skriver ut initialene, men som små bokstaver, samt at det ikke blir skrevet punktum etter siste initial.

eks.

/*
Skriv inn navnet ditt:
ole petter bjarne hansen
Initialene blir: o.p.b.h
Press any key to continue
*/

Utskriften skulle egentlig blitt:

O.P.B.H.

 

Har forsøkt litt med å bruke toupper()-funksjonen, men uten noe særlig hell.

Noen forslag?

 

@zirener

Noe av samme problemet som med funksjonen til Nazgul.

Eksempel på kjøring:

/*
Skriv inn navn: ole petter bjarne hansen
Initialene blir: opbh
Press any key to continue
*/

Utskriften skulle egentlig blitt:

O.P.B.H.

 

 

@kjetil7

Har forsøkt å teste ut boost-varianten din kjetil, men får følgende feilmelding:

fatal error C1083: Cannot open include file: 'boost/algorithm/string.hpp': No such file or directory

 

Hmm.. Noen forslag?

 

 

 

Takker alle som har hjulpet meg så langt.

Håper at noen kan komme med noen innspill slik at jeg kan få dette til å fungere 100%. :hmm:

God helg alle sammen,- undertegnede kommer til å jobbe videre med c++ resten av helga. :)

Lenke til kommentar

Her, denne funker! :)

#include <iostream>
#include <cctype>
#include <vector>

using namespace std;

int main()
{
       cout << "Skriv inn navn: ";

       string name;
       getline(cin, name); 

       cout << "Initialene blir: ";

       cout << static_cast<char>(toupper(name[0])) << '.';;
       for(int j = 0; j != name.size(); j++) 
               if(isspace(name[j])) 
                               cout << static_cast<char>(toupper(name[j+1])) << '.';

       cout << endl;

       return 0;
}

Lenke til kommentar
#include <sstream>
#include <iostream>
#include <string>
#include <cctype>
#include <algorithm>

using namespace std;

string inititaler(std::string& navn);


int main() {

 cout << "Skriv inn navnet ditt: " << endl;
 string navn;
 getline(cin,navn);

 cout << "Initialene blir: " << inititaler(navn) << endl;
}//main



string inititaler(string& navn) {
 size_t pos1,pos2=0;
 stringstream ret;
 ret << navn.substr(0,1);
 while((pos1 = navn.find(" ",pos2)) != string::npos) {
   ret << "." << navn.substr(pos1+1,1);
   pos2 = pos1+1;
 }
 ret << ".";
 string s = ret.str();
 transform(s.begin(),s.end(), s.begin(),toupper);
 return s;
}

Endret av Nazgul
Lenke til kommentar

@zirener

Tusen takk! Fungerer helt utmerket. :)

 

 

@Nazgul

Du har fullstendig rett i at jeg bør kunne se hvor jeg skal endre koden din.. :blush:

(Litt for enkelt å spørre uten å ha prøvd ordentlig selv)

Har fiksa den nå,- var bare en

ret << ".";

-som skulle til. :)

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...