2011-11-19 9 views
5

He formateado una entrada como esta:Lectura de una línea con números enteros y una cadena con espacios

número entero de palabras múltiples cuerdas entero

sé la longitud máxima de varias palabras -string, sin embargo, no sé cuántas palabras contiene. ¿Cómo puedo leerlo?

+0

Al leer una línea a la vez, puede compilar un analizador de subcadenas que le permite enumerar los segmentos utilizando varios terminadores arbitrarios. La respuesta de Kerrek es genial, pero si necesita hacer este tipo de cosas con bastante frecuencia, y necesita una herramienta general de alta eficiencia, ese es el enfoque que encontré que funcionó mejor para nosotros – Mordachai

Respuesta

1

Lea el primer entero. Salta a la parte posterior de la cuerda y salta los dígitos. Luego lee un int a partir de este punto. La parte en el medio es la cadena. Puede no ser 100% correcto pero:

char buf[256], *t = buf, *p, str[256]; 
fread(buf, 1, 256, file); 
int s,e; 
t += sscanf(buf, "%d", &s); 
*p = buf + strlen(buf); 
while (isdigit(*p)) p--; 
sscanf(p, "%d", &e); 
strncpy(str, p, p - t); 
5

Leería primero la línea y convertiría la primera y la última palabra en enteros. Sin apretar:

std::string line; 
std::getline(infile, line); 

size_t ofs_front = line.find(' '); 
size_t ofs_back = line.rfind(' '); 

int front = std::strtol(line.substr(0, ofs_front).c_str(), NULL, 0); 
int back = std::strtol(line.substr(ofs_back).c_str(), NULL, 0); 
std::string text = line.substr(ofs_front, ofs_back - ofs_front); 

Vas a tener que hacer algunas modificaciones para deshacerse de los espacios (por ejemplo, incrementar los desplazamientos de engullir todos los espacios), y se debe añadir un montón de comprobación de errores.

Si desea normalizar todos los interiores espacios dentro del texto, entonces no hay otra solución utilizando flujos de cadena:

std::vector<std::string> tokens; 
{ 
    std::istringstream iss(line); 
    std::string token; 
    while (iss >> token) tokens.push_back(token); 
} 
// process tokens.front() and tokens.back() for the integers, as above 
std::string text = tokens[1]; 
for (std::size_t i = 2; i + 1 < tokens.size(); ++i) text += " " + tokens[i]; 
1

Esto no es tan eficiente como @ KerrekSB de solution, pero otra manera de hacer esto es extraer el primer entero, luego recorrer el resto de la cadena hasta encontrar el segundo entero.

#include <iostream> 
#include <sstream> 

int main() 
{ 
    std::istringstream ss("100 4 words to discard 200"); 
    int first, second; 
    char buf[1000] = {0}; 

    if(!(ss >> first)) { 
    std::cout << "failed to read first int\n"; 
    return 1; 
    } 

    while(!(ss >> second) || !ss.eof()) { 
    if(ss.eof()) { 
     std::cout << "failed to read second int\n"; 
     return 1; 
    } 
    ss.clear(); 

    if(ss.getline(buf, 1000, ' ').bad()) { 
     std::cout << "error extracting word\n"; 
     return 1; 
    } 
    }  

    std::cout << "first = " << first << "\n"; 
    std::cout << "second = " << second << "\n"; 

    return 0; 
} 
+0

@KerrekSB Ambos casos se manejan correctamente – Praetorian

+0

Disculpe, ¡no importa! –

Cuestiones relacionadas