Estoy tratando de dividir una cadena por un delimitador especificado de acuerdo a este ejemplo: http://msdn.microsoft.com/en-us/library/ftsafwz3(v=VS.90).aspx

Mi código se compila sin errores en Visual C++ 2010, pero cuando quiero ejecutarlo, me sale este mensaje de error:

Excepción no controlada en 0x773a15de en Test.exe: 0xC0000005: infracción de Acceso de lectura ubicación 0x00000000.

Aquí está mi código:

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <regex>

using namespace std;

vector<char *> splitString(char in[])
{
vector<char *> parts(15);
char seps[]   = " ,\t\n";
char *next_token1 = NULL;
char *token1 = NULL;
token1 = strtok_s(in, seps, &next_token1);
while ((token1 != NULL))
{
    if (token1 != NULL)
    {
        token1 = strtok_s( NULL, seps, &next_token1);
                    //printf( " %s\n", token1 );
        parts.push_back(token1);
    }
}
return parts;
}

int main(int argc, char * argv[])
{
char string1[] =
    "A string\tof ,,tokens\nand some  more tokens";
vector<char *> parts=splitString(string1);
cout << parts[0] <<endl;
cout << parts[1] <<endl;
return 0;
}

Parece ser ilegal que trato de mostrar el vector de elementos, pero ¿por qué?

El vector de la capacidad debe ser suficiente y un

printf( «%s\n», token1 );

en el bucle while imprime las fichas!

  • Tenga en cuenta que además del problema con el acceso no válido dirigida por hmjd la respuesta, estás tirando el primer token.
InformationsquelleAutor bogus | 2012-10-03

2 Comentarios

  1. 2

    El uso de vector es incorrecta. Se construye con 15 elementos y, a continuación, push_back() se utiliza para añadir las cadenas que añade nuevos elementos después de el período inicial de 15. Esto significa que el primer 15 elementos sin asignar (null):

    std::cout << parts[0] << end; //parts[0] is null

    Ya sea:

    • no asignar previamente los elementos en construcción, o
    • uso operator[] y no push_back() (añadir lazo terminator para proteger a ir más allá del final del vector)

    (Considere la posibilidad de cambiar a std::vector<std::string>.)

    Sólo para mencionar boost::split() que puede genera una lista de tokens (std::vector<std::string>) de una cadena de entrada y permite la especificación de varios delimitadores.

    • Yo incorrectamente hizo esto a reserva de las ranuras de antemano para aumentar la eficiencia. Gracias por tu consejo, ya solucione mi problema!
    • vector de la clase tiene un método para hacer precisamente eso : la reserva(ranuras). Consulte cplusplus.com/reference/vector/vector/reserve para más detalles.
  2. 2

    El problema es general palabra de advertencia: usted está usando strtok (familia) de las funciones en c++. Tenga en cuenta que este de edad API modifica es argumento. Esto con frecuencia no es lo que usted espera, y por esta razón te aconsejo contra el uso de este C función de la librería.

    Además usted está asumiendo que el 15 elementos, va a ser leído, dejando el «excedente» elementos sin inicializar. Esto, también, se traduce en un comportamiento indefinido en el acceso a los elementos.


    Me gustaría sugerir una C++ enfoque, dado que se está utilizando es:

    #include <iostream>
    #include <sstream>
    #include <iterator>
    #include <algorithm>
    
    using namespace std;
    
    vector<std::string> splitString(const char in[])
    {
        std::istringstream iss(in);
        std::istream_iterator<std::string> first(iss), last;
    
        std::vector<std::string> parts;
        std::copy(first, last, std::back_inserter(parts));
        return parts;
    }
    
    int main(int argc, char * argv[])
    {
        const char string1[] = "A string\tof ,,tokens\nand some  more tokens";
        vector<std::string> parts = splitString(string1);
        cout << parts[0] <<endl;
        cout << parts[1] <<endl;
        return 0;
    }

    Para ello se utiliza el hecho de que, por defecto, iostreams se skipws (omitir espacios en blanco)

    • The trouble is, you're using strtok (family of) functions to modify an unmodifiable string literal. No hay ninguna modificación de cadenas literales en la OP del código.
    • cree que puede estar mal</strike>: MSDN dice: Cada llamada a strtok_s modifica strToken mediante la inserción de un carácter nulo después de que el token devuelto por la llamada EDITAR Oh, espera, ya veo lo que quería decir. string1 es inicializa de un literal, no se señala a los datos reales. La fijación de

Dejar respuesta

Please enter your comment!
Please enter your name here